【发布时间】:2012-02-28 11:11:31
【问题描述】:
Oracle 关于原子访问的文档(http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html)这样说:
“一个volatile变量建立了happens-before关系……这意味着……当一个线程读取一个volatile变量时,它看到的不仅仅是volatile的最新变化,还有代码的副作用这导致了变化。”
我很难理解这一点。我了解 volatile 变量是如何工作的(在 >= Java 5 中),但我想知道 java 如何决定什么副作用“导致”了 volatile 变量的变化。
所以我想我的问题是:这个保证有什么副作用?
编辑:
所以我了解到,如果线程 A 修改了一个 volatile 变量,然后线程 B 读取它,那么在写入 volatile 变量之前发生的线程 A 的所有写入相对于线程 B 都是“一致的”(即受线程 A 上述写入影响的变量的缓存值在线程 B) 中无效。如果我错了,请纠正我。
【问题讨论】:
-
您确实对缓存的工作方式有误解,但 volatile write 会刷新 写入缓冲区 而不是缓存(可以手动刷新缓存,但通常您永远不会想要)跨度>
-
我的误解到底是什么?听起来您的答案与 Tom Hawtin 的不同 - 也许您想写一个替代答案?
-
不,这与他的回答并不矛盾,尽管它(他的回答)并不完全完整。缓存不会被刷新(这只会破坏任何性能),但只有修改后的缓存行才会保持一致[简单地说]。它还确保没有投机性读取过去写入(这是非常重要的)。因此,当 CPU 恢复时,所有其他人将/可能知道该写入(以及所有先前的写入)。一般来说,所有 CPU 都在 某个 点使写入可用/可见,但使用 volatile 写入它只是 现在。我不认为 SO 是解释缓存一致性如何工作的好领域。
-
顺便说一句,“冲洗”是指“驱逐”吗?刷新缓存通常意味着驱逐其条目,而不仅仅是传播写入。
-
我不清楚我的意思。忽略那句话。问题:“过去写”是什么意思?
标签: java concurrency atomic volatile side-effects