volatile通过内存屏障约束指令重排序,而非直接禁止;写操作插入StoreStore和StoreLoad屏障,读操作插入LoadLoad和LoadStore屏障,并基于happens-before规则保障跨线程可见性。

Java 中 volatile 并不是直接“禁止”编译器或 CPU 的指令重排序,而是通过在关键位置插入内存屏障(Memory Barrier),向 JVM 和硬件明确发出顺序约束,让相关指令不能跨越屏障移动,从而在多线程场景下保障逻辑上的执行顺序。
靠内存屏障限制指令移动范围
JVM 在生成字节码或 JIT 编译为机器码时,对 volatile 变量的读写操作自动插入四类屏障:
- 写操作前插入 StoreStore 屏障:确保该写之前的所有普通写操作,不会被重排到它之后
- 写操作后插入 StoreLoad 屏障:阻止后续的读操作被提前到该写之前执行
- 读操作前插入 LoadLoad 屏障:保证该读之前的所有普通读操作,不会被重排到它之后
- 读操作后插入 LoadStore 屏障:防止后续的写操作被提前到该读之前
依托 happens-before 规则建立执行顺序
volatile 变量规则是 Java 内存模型(JMM)定义的核心 happens-before 关系之一:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 对一个 volatile 变量的写操作 happens-before 后续对该变量的读操作
- 这个“后续”不要求代码紧邻,只要读发生在写之后(逻辑上或实际执行中)就成立
- 该规则跨线程生效,配合程序次序规则和传递性,可推导出更长的可见性链
只约束自身读写相关的指令顺序
volatile 对重排序的约束有明确边界:
立即学习“Java免费学习笔记(深入)”;
- 只作用于 volatile 读/写与它前后普通读写的相对顺序
- 不保证全局所有指令的绝对顺序,也不影响无关变量之间的重排
- 例如:x = 1; flag = true;(flag 是 volatile),那么 x = 1 一定在 flag = true 之前对其他线程可见
底层靠 lock 指令触发硬件同步
在 x86 平台,volatile 写通常编译为带 lock 前缀的指令(如 lock addl $0x0,(%rsp)),它会强制:
- 将当前 CPU 缓存行数据立即写回主内存
- 使其他 CPU 中对应缓存行失效
- 形成天然的执行顺序锚点,阻止处理器乱序执行跨越该指令

















