java - volatile 变量和其他变量

标签 java multithreading concurrency volatile memory-visibility

以下内容来自经典的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/

相关文章:

java - 如何使用类名动态设置 ArrayList 类型?

java - rJava:从 R 创建零长度 Java 数组

java - 为什么在构造函数不同步的情况下final关键字可以保证安全发布?

scala - Scala 中的 Future 和无限循环

multithreading - 生成比线程更多的任务

java - HSQL、内存数据库、Java 和 PHP 问题

java - 正则表达式从java中的字符串中删除空格,逗号,空格?

vb.net - 如何在后台线程中运行代码并仍然访问UI?

c# - SynchronizationContext.Current 在主线程上为空

concurrency - 关于 DMA 和 CPU 并发