volatile变量的可见性由jvm插入内存屏障实现:写操作插入storestore+storeload屏障,强制刷新至主内存并使其他核心缓存失效;读操作插入loadload+loadstore屏障,强制从主内存加载最新值,二者共同建立happens-before关系。

volatile 变量的可见性不是靠“自动同步”实现的,而是由 JVM 在编译和运行时,针对读写操作插入特定内存屏障,强制工作内存与主内存按序交互。
写操作:强制刷新到主内存
当线程对 volatile 变量执行写操作(assign)后,JVM 会立即插入 StoreStore + StoreLoad 两道屏障:
- StoreStore 屏障:确保该 volatile 写之前的所有普通写操作(如对非 volatile 字段的赋值)都已完成,并已写入主内存;
- StoreLoad 屏障:阻止后续的读/写操作被重排到该 volatile 写之前,同时保证该写操作的结果对其他 CPU 核心可见(通常触发缓存行失效广播,依赖 MESI 协议)。
这使得 volatile 写一旦完成,其新值就已落地主内存,且其他线程无法继续使用旧缓存副本。
读操作:强制从主内存加载最新值
当线程读取 volatile 变量前,JVM 插入 LoadLoad + LoadStore 屏障:
- LoadLoad 屏障:确保该 volatile 读之前的所有读操作(如读其他字段)已完成;
- LoadStore 屏障:禁止后续写操作被提前到该 volatile 读之前执行,同时触发一次主内存重载——即清空本地缓存中该变量对应缓存行,并从主内存或其它核心缓存中拉取最新值(MESI 的 Shared 或 Invalid 状态下会触发总线嗅探)。
因此每次读取,拿到的都是全局最新值,而非工作内存中的陈旧副本。
屏障如何协同 JMM 规则生效
这些屏障不是孤立起作用的,它们与 Java 内存模型(JMM)定义的原子操作深度绑定:
- volatile 写 → 强制触发 store 和 write 操作,跳过工作内存缓存延迟;
- volatile 读 → 强制前置 read 和 load 操作,绕过工作内存旧值复用;
- 两者共同构成一个 happens-before 关系:前一个线程的 volatile 写,happens-before 后续任意线程对该变量的 volatile 读。
这个 happens-before 链,才是跨线程可见性的逻辑基础,而内存屏障是其在硬件与 JVM 层面的落地机制。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











