Volatile是轻量级的synchronized,在多处理器开发中保证了“共享变量”的可见性。Volatile如果得到合适的使用,可以比synchronized执行成本更低,因为它不会引起线程上下文的切换和调度。那么Volatile是如何保证可见性的呢?

在汇编代码中,Volatile修饰的共享变量进行写操作时,会多一条#Lock前缀的指令。该指令在多核处理器下会影响两件事情:

  • 将当前处理器缓存行的数据会写回到系统内存。
  • 这个写回内存的操作会引起在其他CPU里缓存了该内存地址的数据无效。

我们知道,处理器为了提高处理速度,不直接和内存进行通讯,而是先将系统内存的数据读到内部缓存(L1,L2或其他)后再进行操作。那么,处理器完成第一件事情后是如何做到第二件事的呢。这就引出了缓存一致性协议。处理器会通过嗅探检测是否有处理器写内存地址,如果有,那么当前处理器会无效掉自己的缓存行;也就是说,一个处理器修改自己缓存的共享变量后,会回写到内存中,并让其他处理器的相应缓存无效。其他处理器如果要修改,就必须再执行一次缓存行填充。如上通过Volatile就保证了java线程内存模型所有线程看到共享变量的值是一致的。