打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
volatile关键字的理解

  首先volatile只能修饰实例变量或者类变量,不能修饰方法、局部变量、方法参数等。并发的三个至关重要的特性,原子性可见性、有序性,volatile只能保证前面的两个特性,所以使用volatile关键字要在合适的业务场景。

  一、volitile的可见性

  多线程的可见性,简单来说是指多个线程共享的变量修改以后,各个线程都能看到变量已经修改了,并且从主内存中拷贝变量改变后的值。

        

public class TestVisibility {
    private static boolean stopFlag;

    public static void main(String[] args)throws InterruptedException{

        Thread loop = new Thread(()->{
            int i=0;
            while(!stopFlag){
                i++;
            }
            System.out.println("Thread is stopped and evaluated result is:"+i);
        });
        loop.start();
        TimeUnit.SECONDS.sleep(1);
        stopFlag = true;
    }
}

 

  上面的TestVisibility的测试类,预计期望1秒后程序会停止并打印出计算结果,但运行结果是它会一直运行没有停止。

        变量stopFlag是基本数据类型所以线程操作是原子的,单个原子操作是线程安全的,但是只能保证原子性,对其他线程是不可见的,在主线程sleep一段时间后 stopFlag 的修改子线程loop没有感知到,循环会一直继续下去。

        要使loop线程在sleep后正常退出,可以stopFlag前加上volatile关键字就可以了,因为volatile是可以保证可见性的。 

  二、有序性

  有序性:是指按照代码的先后的执行程序。但是由于Java编译器的优化,代码的执行顺序不一定是你编写后代码的顺序。

       

int x=0;
int y=0;
x++;
y=20

  上面的代码执行可能是按照从上至下编写的顺序执行的,但在jvm执行的时候不一定是这样的顺序,有可能 y=20 在x++的前面执行,这就是指令的重排序。

   volatile可以保证有序性。volatile对修饰的变量前后无依赖关系的指令可以随便怎么排序:

1 int x=0;
2 int y=0;
3 volatile z=20;
4 x++;
5 y=20

上面第3行的前后的逻辑不管怎么排列,只要到第3行执行的时候x=0 y=0就可以。对变量z多个线程进行操作,volatile的有序性强制限制修改变量的线程要在读的线程之前。

  

 

  

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
深入理解Java虚拟机内存模型
Volatile关键字在Java多线程编程中的作用与限制
并发编程中的三个概念
你真的了解 volatile 关键字吗?
Java并发编程:volatile关键字解析
学习Java多线程之volatile域
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服