以下内容来自经典的Concurency in Practice
:
When thread A writes to a volatile variable and subsequently thread B reads the same variable, the values of all variables that were visible to A prior to writing to the volatile variable, become visible to B after reading the volatile variable.
我不确定我是否真的能理解这句话。例如,所有变量 在此上下文中的含义是什么?这是否意味着使用 volatile
也会对非 volatile 变量的使用产生副作用?
在我看来,这句话有一些我无法理解的微妙含义。
有帮助吗?
最佳答案
您问题的答案在 JLS #17.4.5 中:
A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.
所以如果在一个线程中你有
aNonVolatileVariable = 2 //w1
aVolatileVariable = 5 //w2
随后在另一个线程中:
someVariable = aVolatileVariable //r1
anotherOne = aNonVolatileVariable //r2
您可以保证 anotherOne
将等于 2,即使该变量不是可变的。所以是的,使用 volatile 也会对非 volatile 变量的使用产生副作用。
更详细地说,这是由于同一部分中 Java 内存模型 (JMM) 提供的 2 个其他保证:线程内顺序和传递性(hb(x,y) 表示 x 发生在 y 之前):
If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
[...]
If hb(x, y) and hb(y, z), then hb(x, z).
在我的例子中:
- hb(w1, w2) 和 hb(r1, r2)(线程内语义)
- hb(w2, r1) 因为 volatile 保证
因此您可以通过传递性得出 hb(w1, r2) 的结论。
并且 JMM 保证程序的所有执行将顺序一致(即看起来没有任何内容被重新排序)如果它与 happens-before 关系正确同步。所以在这种特定情况下,非 volatile 读取保证看到非 volatile 写入的效果。
关于java - volatile 变量和其他变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12438464/