顺序一致性易变解释
我正在观看来自java jpoint会议的video。
我对来自Alexey Shipilev报告的幻灯片有疑问:
幻灯片上的非英语版请原谅。 实际上作者说变量集是不可能的
r1 = 1 (Y) r2 = 0 (x) r3 = 1 (x) r4 = 0 (Y)
根据video,他暗示这显然是。
根据JMM,有人可以澄清为什么这个价值设定不可能?
PS
如果我理解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(); } }
相信我明白了。
让我们说我们有4个线程。 t1-t4(根据图片从左到右)
t3读取y然后读取x ,我们看到结果
y=1 x=0
这意味着序列如下:
- t1写y
- t3读y
- t3读取x
- t2写x
它是唯一可行的序列。
让我们检查t4读数:
x=1 y=0
根据t3的推理,它意味着
t2 write
在t1 write
之前发生,但它与t3输出相矛盾,因此不可能
您可以为此代码构建详尽的SC执行列表,并且不会实现SC执行产生(1,0,1,0)。
在模型方面,它很容易争论。 同步顺序(SO)一致性表明同步读取应该看到SO中的最后一次同步写入。 SO-PO一致性表示SO应该与程序顺序一致。
这允许通过矛盾来描绘certificate。 假设存在产生(1,0,1,0)的执行。 然后,在那些执行中,由于SO的一致性,读取的零必须按此顺序:
(r2 = x):0 --so--> (x = 1) [1] (r4 = y):0 --so--> (y = 1) [2]
…并且其他两个读取必须按此顺序进行写入以查看它们(由于SO一致性):
(x = 1) --so--> (r3 = x):1 [3] (y = 1) --so--> (r1 = y):1 [4]
……此外,由于SO-PO的一致性:
(r1 = y):1 --po--> (r2 = x):0 [5] (r3 = x):1 --po--> (r4 = y):0 [6]
这会产生奇怪的传递性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]
请注意,对于上面执行中的任何一对动作A!= B,我们可以说(A --so--> B)
和(B --so--> A)
– 这称为对称性。 根据定义,SO是总顺序,总顺序是反对称的 ,这里我们有对称的顺序。 我们已经陷入矛盾,因此不存在这样的执行。 QED