JVM volatile用于保证程序可见性顺序性,但是不保证原子性。volatile实现原理是通过在操作变量之前,多加一个lock前缀指令,通过汇编可以看到这个前缀指令。

当谈到顺序性时常会提到内存屏障,常见的硬件层面内存屏障有:sfence lfence mfencelock前缀指令不是内存屏障,而是一种锁,执行时会锁住内存子系统来确保执行顺序,甚至跨多个CPU,JVM利用lock前缀指令的特点实现了可见性顺序性,lock前缀指令实现可见性比较好理解,主要是利用CPU提供的缓存一致性协议(例如Intel的MESI),当然更差一点的还有lock总线的方式(限制CPU访问内存)。

JMM层面为了实现顺序性,又抽象出四个内存屏障的概念:LoadLoad StoreStore LoadStore StoreLoad,字节码层面并没有内存屏障的指令,JVM的C++代码会有四个同名函数与之对应,JVM遇到volatile变量便会在其前后执行对应的函数,从而实现内存屏障,具体来说:

LoadLoadBarrier
volatile 读操作
LoadStoreBarrier

StoreStoreBarrier
volatile 写操作
StoreLoadBarrie