JMM中的因果关系似乎是其中最令人困惑的部分。关于JMM因果关系和并发程序中允许的行为,我有几个问题。
据我所知,当前的JMM总是禁止因果循环。(我说的对吗?)
现在,根据JSR-133文档,第24页,图16,我们有一个示例:
最初的x = y = 0
线程1:
r3 = x;
if (r3 == 0)
x = 42;
r1 = x;
y = r1;
线程2:
r2 = y;
x = r2;
从直觉上看,r1 = r2 = r3 = 42
似乎是不可能的。然而,它不仅被尽可能地提到,而且在JMM中也被“允许”。
对于这种可能性,我不能理解的文档中的解释是:
编译器可以确定分配给
x
的唯一值是0和42。从这一点,编译器可以推断,在我们执行r1 = x
的时候,要么我们刚刚对x
执行了42的写操作,要么我们刚刚读取了x
并看到了值42。在任何一种情况下,读取x
查看值42都是合法的。然后,它可以将r1 = x
更改为r1 = 42
;这将允许将y = r1
转换为y = 42
并更早地执行,从而导致有问题的行为。在这种情况下,首先提交对y
的写入。
我的问题是,它到底是一种什么样的编译器优化?(我对编译器一无所知。)由于42是有条件地编写的,所以当满足if
语句时,编译器如何决定继续编写x
其次,即使编译器做了这种推测性的优化,然后提交y = 42
,最后进行r3 = 42
,这不是违反了因果循环吗,因为现在已经没有因果区别了?
事实上,在同一文档(图7的第15页)中有一个示例,其中提到类似的因果循环是不可接受的。
那么为什么这个执行顺序在JMM中是合法的呢?
https://stackoverflow.com/questions/13271649
复制相似问题