多线程Java易失性和可见性
据我所知,volatile背后的底层机制保证不会对操作进行重新排序。然而,我很难看到它是如何保证可见性的
即线程A写入一个值。然后线程B从内存而不是缓存中读取它(以保证缓存一致性)。我知道CAS确实做到了这一点,但内存障碍是如何做到这一点的呢
你可以在下面搜索框中键入要查询的问题!
据我所知,volatile背后的底层机制保证不会对操作进行重新排序。然而,我很难看到它是如何保证可见性的
即线程A写入一个值。然后线程B从内存而不是缓存中读取它(以保证缓存一致性)。我知道CAS确实做到了这一点,但内存障碍是如何做到这一点的呢
# 1 楼答案
通用内存屏障是一种特定于CPU的指令,表示“使读缓存无效”或“提交写缓存”,或两者兼而有之。在x86这样的强顺序CPU上,“使读缓存无效”是不可操作的,因为缓存总是一致的
# 2 楼答案
Volatile“使用”特定于硬件的指令来实现它。这里是in-depth article about JSR-133 and Memory Barriers for Compiler Writers
因为如果你在
AtomicInteger
中查看示例,你会看到# 3 楼答案
内存屏障由CPU实现,以始终显示最新值。如果没有CPU支持,这是无法实现的
这是一个常见的误解,即访问主内存,但这将是非常缓慢的。相反,二级缓存之间存在缓存一致性总线
在一级缓存之前有一个写存储缓冲区,但CPU确保核心之间的缓存线是最新的