volatile通过强制读写主内存和插入内存屏障,保证变量可见性与禁止指令重排序,从而严格遵循JMM的可见性和有序性规则,但不保证复合操作原子性。

volatile 是 Java 中落实 JMM(Java 内存模型)规范最直接、最轻量的体现方式之一。它不改变变量存储位置,也不创建锁,而是通过强制约束读写行为,让变量的访问严格遵循 JMM 定义的可见性与有序性规则。
volatile 如何保障内存可见性
JMM 规定:线程对共享变量的操作,必须先从主内存读取副本到工作内存,修改后再刷回主内存。但普通变量可能因缓存、编译优化等原因,导致其他线程长期看不到最新值。
volatile 变量打破了这种“缓存自由”:
- 每次读取 volatile 变量时,JVM 强制从主内存重新加载,跳过工作内存中可能过期的副本;
- 每次写入 volatile 变量后,JVM 立即将新值刷新到主内存,并使其他线程工作内存中该变量的副本失效;
- 这相当于为该变量建立了一条“直通主内存”的通道,确保所有线程看到的是同一时刻的最新值。
volatile 如何限制指令重排序
JMM 允许编译器和 CPU 在不改变单线程语义的前提下重排指令,以提升性能。但这在多线程下可能破坏逻辑——比如“初始化对象 + 设置标志位”被重排,导致其他线程看到未初始化完成的对象。
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
volatile 通过插入内存屏障(Memory Barrier)禁止特定重排序:
- 写 volatile 变量前的所有操作,不能被重排到该写操作之后;
- 读 volatile 变量后的所有操作,不能被重排到该读操作之前;
- 这就形成了一个天然的 happens-before 边界:对 volatile 的写操作 happens-before 后续任意线程对该 volatile 的读操作。
volatile 与 JMM 的协同本质
JMM 是一套抽象规则,而 volatile 是唯一一个由语言层面直接映射到这些规则的关键字。它不提供原子性(如 i++ 仍非原子),也不保证临界区互斥,但它精准锚定了 JMM 的两个核心承诺:
- 可见性:用读写直达主内存的方式,兑现“一个线程修改,另一个线程能立即感知”的约定;
- 有序性:用内存屏障固化执行顺序,兑现“跨线程操作之间存在确定先后关系”的约定。
换句话说,声明一个变量为 volatile,就是告诉 JVM:“请按 JMM 最严格的可见性和有序性要求来处理它”。
常见误区提醒
容易混淆的点需要特别注意:
- volatile 不等于 synchronized:它不阻塞线程,也不构成原子临界区;
- volatile 变量本身读写是原子的(32位基本类型及引用),但复合操作(如 count++)仍需额外同步;
- JMM 是规范,volatile 是实现该规范某部分语义的具体机制,二者不是并列关系,而是“规范—实现”关系。

















