volatile是JVM提供的轻量级的同步机制。volatile关键字能够保证并发编程的三大特性中的可见性,有序性。但是不能保证原子性。
保证可见性:
经过volatile修饰的变量,在本地内存中修改之后,会立即刷回主内存中。当主内存中的共享变量修改之后,其他线程的本地内存会立即同步获取到这个最新的值。
保证有序性:
通过禁止指令重排优化来保证有序性。禁止指令重排优化是通过内存屏障来实现的。
内存屏障就是CPU或者编译器对内存随机访问的一个同步点,使得对该点之前的操作在该点之后的操作之前。避免代码重排序。
内存屏障粗分类:
内存屏障细分类:
LoadLoad: 保证load1在load2之前执行。
StoreStore:保证store1保存在store2保存之前。
LoadStore:保证load1读取数据在store1写入数据之前。
StoreLoad:保证store保存数据在load读取数据之前。
单一赋值可以,复合赋值是禁止的。一般用来保存某个状态,判断业务是否结束。比如boolean值的flag。
volaile修饰的变量具有可见性。
对于写操作,本地内存中修改后,会立即刷回主存中。
对于读操作,本地内存会从主存中获取最新的值。
JMM在指令序列中通过插入内存屏障来禁止指令重排,保证有序性。
对于volatile写操作:在volatile写操作之前插入StoreStore指令,在volatile写操作之后插入StoreLoad指令来保证指令的有序。
对于volatile写操作:在volatile读操作之后插入LoadLoad指令和LoadStore指令,保证指令的有序。
参考:
1.《Java并发编程的艺术》
2. JMM与volatile