volatile读开销接近普通变量,因仅插入loadload/loadstore屏障并依赖mesi协议同步;写开销为普通写的2–5倍,因需storestore/storeload屏障及缓存同步,但远低于synchronized或锁机制。

volatile 读写操作的性能开销不能简单用“快”或“慢”概括,而要结合内存访问路径、屏障指令和具体使用模式来评估。它比普通变量读写略重,但远轻于 synchronized 或锁机制。
volatile 读操作的开销相对较低
读取 volatile 变量时,JVM 会插入 LoadLoad 和 LoadStore 内存屏障,强制从主内存(或最新缓存行)加载值,跳过线程本地缓存中的陈旧副本。现代 CPU 的缓存一致性协议(如 MESI)通常能高效完成该同步,因此多数场景下读开销接近非 volatile 变量——尤其在变量未频繁跨核争用时。
volatile 写操作有明显但可控的额外成本
写入 volatile 变量会触发 StoreStore 和 StoreLoad 屏障:
- StoreStore:确保之前所有普通写操作已刷新到缓存/主内存
- StoreLoad:强制后续读操作等待本次写完成,防止重排序,也隐含一次缓存同步(如发送 invalidate 消息)
这带来两方面影响:一是延迟增加(通常几十纳秒量级),二是可能引发总线流量上升或缓存行失效风暴(尤其多线程高频写同一 volatile 变量时)。
实际性能受使用方式影响更大
开销高低不只取决于关键字本身,更取决于怎么用:
- 单次写 + 多次读(如状态标志位):整体开销极小,是 volatile 最推荐的场景
- 高频率写(如每微秒更新一次计数器):可能成为瓶颈,尤其在多核密集争用下
- 与非 volatile 字段共处同一缓存行:可能引发“伪共享”(false sharing),放大性能损失
- 在无竞争路径中使用:JIT 编译器有时可做有限优化,但不会消除内存语义
对比其他同步机制更易判断取舍
volatile 写的开销约为普通写操作的 2–5 倍;而 synchronized 方法调用或 ReentrantLock.lock() 通常带来 10–100 倍以上的开销(含上下文切换、队列管理等)。AtomicInteger.incrementAndGet() 因底层使用 CAS,其开销介于 volatile 写与 synchronized 之间,且随竞争加剧显著上升。
所以评估时应问:这个变量是否只需保证可见性和有序性?是否涉及复合操作?是否写少读多?满足这些,volatile 就是性价比最高的选择。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











