volatile关键字通过直读主内存、强制刷回、缓存行锁定、invalidate消息及内存屏障,确保写操作对其他线程可见且建立happens-before关系,从而保证修改后相关操作结果的可见性。

volatile 关键字通过强制线程绕过工作内存、直连主内存,配合硬件级缓存一致性协议与内存屏障,确保一个线程对变量的修改能被其他线程“看到”——不是实时推送,而是“一旦读到新值,就一定能看到该写之前所有相关操作的结果”。
直读主内存 + 强制刷回
普通变量读写发生在工作内存(CPU缓存)中,修改可能长期滞留在本地;而 volatile 变量:
- 每次读取都必须从主内存重新加载,不使用缓存副本
- 每次写入都立即刷新到主内存,不等待写缓冲区批量提交
触发缓存一致性协议(如MESI)
当一个CPU核心写 volatile 变量时:
- 锁定对应缓存行(Cache Line Locking)
- 将修改值写入主内存
- 向其他核心发送 Invalidate 消息,使其本地缓存副本失效
- 其他核心下次读该变量时,因缓存失效,必须从主内存重新加载
插入内存屏障阻止重排序
编译器和CPU为优化性能常重排指令,但 volatile 会在关键位置插入屏障:
- volatile 写前插入 StoreStore 屏障:禁止其前面的普通写重排到它之后
- volatile 写后插入 StoreLoad 屏障:禁止其后面的普通读重排到它之前
- volatile 读后插入 LoadLoad 和 LoadStore 屏障:确保后续读写不会提前执行
依托 happens-before 规则建立逻辑可见性链
Java 内存模型不依赖物理时间顺序,而是靠 happens-before 关系保证语义:
- 线程 A 执行 flag = true(flag 是 volatile),happens-before 线程 B 执行 if (flag)
- 只要 B 读到了 true,JMM 就保证 B 能看到 A 在 flag = true 之前做的所有操作(比如 data = 42)
- 这不是“B 一定会很快读到 true”,而是“B 一旦读到 true,data 的值就一定是 42”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











