百木园-与人分享,
就是让自己快乐。

volatile 关键字的 用法

volatile关键字

什么是可见性?

可见性是指线程A改变变量的值后,线程B可以马上看到更改后变量的值

volatile的作用

关键字volatile提示线程每次从共享内存中读取数据,而不是从私有内存中读取,这样就保证了同步数据的可见性

关键字volatile适用的场景

当想实现一个线程对一个变量进行修改,希望其他线程可以取到最新的值的时候。就需要对变量使用volatile关键字了

我们举一个例子:

import static java.lang.Thread.sleep;

public class VolatileTest {
    public static boolean flag  = true;

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(\"线程1 开始!\");
                while(flag){

                }
                System.out.println(\"线程1 结束!\");
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(\"线程2 开始!\");
                flag = false;
                System.out.println(\"flag = \" + flag);
            }
        });

        t1.start();
        sleep(2000);
        t2.start();

    }
}

  • 运行结果
    image

我们可以看到:程序在一直运行,进入了死循环,那么是什么原因造成出现了死循环呢?

  • 我么在启动线程t1之后,变量“public static boolean flag = true;”存在于公共堆栈及线程私有的堆栈中,
    t1运行后一直在线程私有堆栈中取得的flag的值是true,而线程2的代码“flag = false;”,修改的是公共堆栈中的
    flag,所以t1线程私有堆栈中的flag仍然是true。

解决方法 -添加volatile关键字

修改“public static volatile boolean flag = true;”,我们再次运行程序
image

volatile是否具有原子性?

关键字volatile最大的缺点是不支持原子性,如果修改实例中的数据,比如i++,这样的操作不是原子操作,分为三步

  • 从内存中取i的值
  • 计算i的值
  • 将i的值存入内存中

如果在第二步计算i的值时,其他线程读取i的值,并对i进行修改,这个时候就会出现脏数据,解决方法是使用synchronized关键字

  • 参考资料《Java多线程编程核心技术 第二版》

来源:https://www.cnblogs.com/classicltl/p/16224918.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » volatile 关键字的 用法

相关推荐

  • 暂无文章