我看过这个答案,并说明了如何:
在新的内存模型下,当线程A写入易失性
变量 V,线程 B 从 V 读取任何变量值
现在保证在写入 V 时对 A 可见
对 B 可见。
因此,给出示例:
public class Main {
static int value = -1;
static volatile boolean read;
public static void main(String[] args) {
Thread a = new Thread(() -> {
value = 1;
read = true;
});
Thread b = new Thread(() -> {
while (!read);
System.out.println("Value: " + value);
});
a.start();
b.start();
}
}
是否更改为value
(从 -1 到 1)保证对线程 b 可见,尽管value
(only read
)?
如果是这样,考虑到为了对另一个线程可见而执行的一系列更改,除了最后一个变量之外,是否有任何目的使任何变量更改为易失性?
是的,更改为value
保证对线程 b 可见。
JLS 17.4.4。同步顺序 says:
- 写入易失性变量v(§8.3.1.4)同步于所有后续读取v由任何线程(其中“后续”是根据同步顺序定义的)。
JLS 17.4.5。订单前发生 says:
两个动作可以由一个命令发生在之前关系。如果一个动作发生在之前另一个,那么第一个对第二个可见并且在第二个之前排序。
如果我们有两个动作x and y, 我们写hb(x, y)表明x 发生在 y 之前.
-
If x and y是同一线程的操作,并且x出现在之前y按照程序顺序,那么hb(x, y).
-
有一个发生在之前从对象的构造函数的末尾到该对象的终结器(第 12.6 节)的开头的边缘。
-
如果一个动作x 同步于以下动作y,那么我们还有hb(x, y).
-
If hb(x, y) and hb(y, z), then hb(x, z).
第 1 条说value = 1
发生在之前 read = true
.
第 3 条说的是read = true
发生在之前 !read
.
第 1 条说!read
发生在之前 "Value: " + value
.
第 4 条说的是value = 1
发生在之前 "Value: " + value
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)