volatile写插入storestore+storeload屏障,确保前置普通写先完成并刷回主内存、后置读写不重排且触发缓存失效;读插入loadload+loadstore屏障,禁止后续读写重排到其前,并强制加载最新值。

volatile 的内存屏障不是凭空插入的,而是由 JVM 在编译期和运行时,针对 volatile 变量的 读 和 写 操作,按语义严格插入四类屏障,每类都承担明确的约束职责。理解关键在于:屏障不是修饰变量本身,而是绑定在每次对 volatile 变量的读/写指令上。
写操作插入 StoreStore + StoreLoad 屏障
当线程执行 volatile 变量的写(如 x = 1),JVM 确保:
- StoreStore 屏障:该写之前所有普通变量的写操作,必须先完成并刷入主内存,不能被重排序到它之后;
- StoreLoad 屏障:该写之后的任意读或写操作,都不能被重排到它之前;同时强制将该 volatile 值立即写回主内存,并触发缓存行失效广播(基于 MESI 协议),使其他 CPU 核心缓存中对应变量的副本变为 Invalid 状态。
读操作插入 LoadLoad + LoadStore 屏障
当线程执行 volatile 变量的读(如 int v = x),JVM 确保:
- LoadLoad 屏障:该读之前的所有普通变量读操作,必须先完成,不能被重排到它之后;
- LoadStore 屏障:该读之后的所有普通变量写操作,不能被重排到它之前;同时强制清空本地缓存中该变量所在缓存行,并从主内存或其它核心缓存中拉取最新值(MESI 的 Shared 或 Invalid 状态下会触发总线嗅探)。
屏障协同 JMM 构建 happens-before 关系
这些屏障本身不直接“同步数据”,而是为 Java 内存模型(JMM)提供硬件与 JVM 层面的执行保障:
- volatile 写 → 强制触发 store + write,跳过工作内存缓存延迟;
- volatile 读 → 强制前置 read + load,绕过工作内存旧值复用;
- 前一个线程的 volatile 写,happens-before 后续任意线程对该变量的 volatile 读 —— 这个逻辑链才是跨线程可见性的基础,而内存屏障是它的落地机制。
硬件层面常通过 lock 前缀指令实现
在 x86 平台上,JVM 通常将 volatile 写编译为带 lock 前缀的指令(如 lock xchg)。该指令天然具备:
- 写回主内存(cache line flush);
- 锁定总线或缓存一致性协议(如 MESI)下的缓存行,使其他核心缓存失效;
- 隐式包含 StoreLoad 屏障效果(即全屏障),因此 JVM 在 x86 上可省略部分显式屏障插入,但语义不变。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











