volatile 是 Java 的一个变量修饰符关键字,被 volatile 修饰的变量具有以下特性:
今天,我们研究一下 volatile 的底层实现原理。
首先,介绍一下内存可见性的概念,内存可见性:是当某一线程修改了一个共享变量的值,则其他线程能读到这个共享变量修改后的值。
然后,我们了解一下计算机的存储层次结构:
寄存器 -> 高速缓存 -> 内存 -> 外存
接下来我们将一个使用 volatile 关键字的程序,反编译成汇编代码,看看对被 volatile 修饰的变量,进行写操作时,CPU 会做什么事情。
Java 代码:
public class VolatileInstance {
public volatile static Integer instance;
public static void main(String[] args) {
instance = 1;
}
}
汇编代码:
0x0000000003a6a2c3: lock add dword ptr [rsp],0h ;*putstatic instance
; - org.example.chapter01.VolatileInstance::main@4 (line 14)
编译后,我们发现了一条带有 LOCK 前缀的指令,那么这个 LOCK 前缀的指令做了什么事情呢?
volatile 实现原则:
1> LOCK 前缀指令会引起处理器缓存回写到内存。
Lock 前缀指令导致在执行指令期间,声言处理器的 LOCK# 信号。在多处理器环境下,LOCK# 信号确保在声言该信号期间,处理器可以独占任何共享内存(因为它会锁住总线,导致其他CPU不能访问内存,所以实现了独占)。
2> 一个处理器的缓存回写到内存会导致其他处理器的缓存无效。
使用缓存一致性协议:MESI(修改、独占、共享、无效),来保证缓存一致性。
原文:https://www.cnblogs.com/chen-jia-cheng/p/14702855.html