volatile关键字实现原理

volatile关键字实现原理

在CPU计算时,需要将数据从主存经过PC总线拷贝到寄存器中进行运算,那么Java中的volatile关键字实现原理是什么呢?

volatile的两层语义

1、不同线程间的内存可见性

2、禁止指令重排序

对于内存可见性比较好理解,这里针对指令冲排序简单解释

指令重排序:在JDK中,JAVA语言为了维持顺序内部的顺序化语义,也就是为了保证程序的最终运行结果需要和在单线程严格意义的顺序化环境下执行的结果一致,程序指令的执行顺序有可能和代码的顺序不一致,这个过程就称之为指令的重排序。指令重排序的意义在于:JVM能根据处理器的特性,充分利用多级缓存,多核等进行适当的指令重排序,使程序在保证业务运行的同时,充分利用CPU的执行特点,最大的发挥机器的性能

被volatile关键字修饰的变量内存可见性的实现原理

volatile boolean flag = false;

Thread1:

while(!flag) {
        continue;
}
……
……

Thread2:

……
……
flag = true;
……
……

通过上面代码可知,Thread1在代码逻辑执行到while(!flag)的地方会进行循环等待,在这个过程中,会等待flag值被修改为true,此时Thread2启动,在代码flag = true的地方修改了flag的值,这时如果没有使用volatile修饰,可能Thread2的修改结果不能及时同步到Thread中,如果使用volatile关键字修饰,就能立刻被Thread1发现,发现过程如下

1、Thread1占用CPU核1,flag通过PCI总线拷贝到对应的寄存器存储空间中,进行运算(while)

2、Thread2占用CPU核2,同样,flag通过PCI总线拷贝到对应的寄存器存储空间中,进行运算(flag=true)

3、Thread2更新的flag值刷新到主存,经过PCI总线时,通过PCI总线负责通知Thread1(核1)中的flag值过期并重新拉去新的值,同时刷新主存中flag的值