You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Brian Goetz廉价读写锁示例中volatile修饰是否冗余?

关于CheesyCounter中volatile是否冗余的澄清

你的思路有一定道理,但忽略了Java内存模型里一个关键细节——同步块的可见性保障只覆盖进入/退出同步块的操作,无锁的读操作并不在这个保障范围内。咱们一步步拆解清楚:

你觉得volatile冗余的逻辑误区

你说的没错:所有写入value的操作都在synchronized块中执行,当线程退出同步块时,会将工作内存中的value刷新到主内存,这部分完全符合JMM的happens-before规则。但问题恰恰出在**无锁的读操作getValue()**上。

去掉volatile会产生什么问题?

当线程调用getValue()时,它没有进入任何同步块,JMM不会强制它从主内存读取value的最新值。读线程的工作内存中可能已经缓存了value的旧副本,并且会一直复用这个副本,完全看不到其他线程在同步块中更新到主内存的新值。

举个实际场景就能明白:

  • 线程A循环调用increment(),每次都在同步块里更新value并刷新到主内存
  • 线程B循环调用getValue(),如果没有volatile修饰value,B可能一直返回最初的0,永远看不到A更新后的数值

volatile在这里的核心作用

加上volatile修饰后,会强制两个关键行为:

  • 每次getValue()读取value时,必须直接从主内存获取最新值,不会复用工作内存的缓存副本
  • 每次写入value(即使在同步块里)后,立即刷新到主内存(这部分和同步块的效果重叠,但核心是修正了无锁读的行为)

简单总结:同步块保证了写入操作的原子性和写入到主内存的动作,而volatile保证了无锁读操作能看到主内存的最新值,二者是互补关系,完全不是冗余的。

内容的提问来源于stack exchange,提问作者Javadee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:23:42