volatile关键字通过强制读写直通主内存并触发缓存一致性协议,确保多线程下变量修改的实时可见性,但仅保障单次读写操作的可见性与有序性,不保证原子性或复合操作的安全性。

volatile 关键字通过强制线程绕过本地工作内存(如 CPU 缓存或寄存器),直接与主内存交互,来保证多线程环境下变量的实时可见性。
核心机制:读写都直通主内存
Java 内存模型(JMM)规定,每个线程都有自己的工作内存,普通变量可能长期停留在其中,不及时同步到主内存。volatile 改变了这一行为:
- 每次读 volatile 变量:必须从主内存重新加载,不使用缓存副本
- 每次写 volatile 变量:必须立即刷新回主内存,不延迟、不合并
- 写操作还会触发缓存一致性协议(如 MESI),使其他 CPU 中该变量所在缓存行失效
它解决的是“改了但对方看不到”的问题
比如一个布尔标志 running 控制循环:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 线程 A 执行 running = false → 立即写入主内存,并让其他核缓存失效
- 线程 B 下一次执行 while (running) → 强制从主内存读取,拿到 false,及时退出
- 没有 volatile 时,线程 B 可能永远读自己缓存里的旧值,陷入死循环
关键前提:仅对单次读/写有效
volatile 的可见性保障只作用于该变量本身的读或写动作,不延伸到其他字段或复合逻辑:
立即学习“Java免费学习笔记(深入)”;
- ✅ 安全:单独赋值 flag = true 或单独判断 if (flag)
- ❌ 不安全:像 count++(含读+改+写三步)、if (flag && data != null)(data 不可见)
- ⚠️ 注意:volatile 引用类型(如 volatile List<String>)只保证引用地址变更可见,不保证内部元素状态同步
不是锁,也不提供互斥
volatile 不会阻塞线程、不造成上下文切换,也没有临界区概念:
- 它不阻止多个线程同时读写——只是确保每次读都能看到最新写入值
- 它不保证原子性,所以不能替代 synchronized 或 AtomicInteger 处理计数、状态转换等场景
- 它和 synchronized 是互补关系:前者轻量保可见+有序,后者重量保原子+互斥+可见

















