伪共享与Java内存模型:volatile关键字的缓存行刷新疑问
public class Counter { public volatile long count1 = 0; public volatile long count2 = 0; }
针对你的疑问,直接拆解核心逻辑:
缓存行的刷新逻辑是硬件行为,而非volatile的特性
CPU通过缓存一致性协议(如MESI)维护缓存的一致性,只要两个变量处于同一缓存行,当其中一个变量被修改(无论是否是volatile),其他核心的对应缓存行会被标记为无效。这是硬件层面的自动操作,和volatile关键字本身无关。volatile写会触发缓存一致性的连锁反应
当线程A更新volatile变量count1时,volatile的语义会触发内存屏障,强制将修改同步到主存。这一动作会触发缓存一致性协议,标记所有其他核心中包含count1的缓存行为无效。读取同一缓存行的变量时的行为
当线程B读取同一缓存行的变量(不管是不是volatile):
- 如果本地缓存行已失效,CPU会从主存重新加载整个缓存行,所以该缓存行内的所有变量都会被更新到最新值。
- 若读取的是volatile变量(如
count2),JMM会额外保证读取操作不会被指令重排序,且每次读取都直接获取最新值;若为非volatile变量,编译器可能做缓存优化(比如把值存在寄存器),但缓存行失效时依然会触发整行刷新——只是非volatile变量的可见性不被JMM承诺。
- 关键误区
volatile并没有“主动刷新同一缓存行所有变量”的特性,它只保证自身变量的可见性和有序性。同一缓存行其他变量的刷新,是硬件缓存一致性协议的副作用,而volatile的写操作只是触发了这个连锁反应的起点。
内容的提问来源于stack exchange,提问作者alfer
相关产品推荐
相关产品推荐

