gst*_*low 4 java concurrency multithreading volatile java-memory-model
我正在观看 java jpoint 会议的视频。
我对以下来自Alexey Shipilev报告的幻灯片有疑问:
对不起,幻灯片上的非英语。实际上作者说变量集是不可能的
r1 = 1 (Y)
r2 = 0 (x)
r3 = 1 (x)
r4 = 0 (Y)
Run Code Online (Sandbox Code Playgroud)
根据视频,他暗示显然是这样。
有人可以澄清为什么根据 JMM 设置这个值是不可能的吗?
聚苯乙烯
如果我理解 Alexey 符号是正确的,它会遵守以下代码:
public class SequentialConsistency {
static volatile int x;
static volatile int y;
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
x = 1;
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
y = 1;
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("r1=" + x + ", r2=" + y);
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("r3=" + x + ", r4=" + y);
}
}).start();
}
}
Run Code Online (Sandbox Code Playgroud)
您可以为此代码构建详尽的 SC 执行列表,并实现无 SC 执行收益率 (1, 0, 1, 0)。
在模型方面,很容易争论。同步顺序 (SO) 一致性表示同步读取应该看到 SO 中的最后一个同步写入。SO-PO 一致性表示 SO 应该与程序顺序一致。
这允许通过矛盾来勾画证明。假设存在 yield (1, 0, 1, 0) 的执行。然后,在那些看到零的执行中,由于 SO 一致性,必须按此顺序读取:
(r2 = x):0 --so--> (x = 1) [1]
(r4 = y):0 --so--> (y = 1) [2]
Run Code Online (Sandbox Code Playgroud)
...另外两个读取必须按此顺序写入才能看到它们(由于 SO 一致性):
(x = 1) --so--> (r3 = x):1 [3]
(y = 1) --so--> (r1 = y):1 [4]
Run Code Online (Sandbox Code Playgroud)
...此外,由于 SO-PO 的一致性:
(r1 = y):1 --po--> (r2 = x):0 [5]
(r3 = x):1 --po--> (r4 = y):0 [6]
Run Code Online (Sandbox Code Playgroud)
这会产生奇怪的循环传递 SO:
(r2 = x):0 --so--> (r3 = x):1 --so--> (r4 = y):0 --so--> (r1 = y):1 --so--> (r2 = x):0
[1,3] [6] [2,4] [5]
Run Code Online (Sandbox Code Playgroud)
请注意,对于上述执行中的任何一对动作 A != B,我们可以说(A --so--> B)和(B --so--> A)-- 这称为对称。根据定义,SO 是全序,全序是反对称的,这里我们有对称的。我们遇到了矛盾,因此这种执行不存在。QED