如何理解JSR-133 Happens-Before太弱了图6/7

时间:2015-12-01 06:01:49

标签: java java-memory-model

JSR-133中,有两个例子表明状态可能是正确同步的程序。

第一个例子由图6给出:

x == y == 0

然后,线程1通过以下方式修改状态:

r1 = x; 
if (r1 != 0) 
y = 1; 

和线程2通过以下方式修改状态:

r2 = y;
if (r2 != 0)
x = 1;

作者声明此程序已正确同步,但是,此程序的执行导致r1 == r2 == 1。后一个价值怎么可能呢?

此外,图7表示初始状态:

x == y == 0

修改主题1:

r1 = x; 
y = r1; 

和线程2执行:

r2 = y;
x = r2;

这怎么会导致r1 == r2 == 42

2 个答案:

答案 0 :(得分:1)

图6 是JMM的 out of an air air 限制的示例。由于没有字段标记为volatile,因此通常允许JVM对示例代码应用优化。这可能会导致惊人的结果。

假设线程1 观察到x = 1为真。现在不要担心,情况可能如此。在这种情况下,线程将设置y = 1。然后,后一种观察将证明x = 1初始观察到的是循环推理的合理性。如果这是真的,x = y = 1将是一个合法的结果,JVM可以简单地替换两个线程中的代码来写每个值。 JMM禁止这种推理形式,x = y = 0是根据JMM的唯一合法结果。

图7 中提出了类似的论点。再次,假设线程1 观察x = 42。在这种情况下,线程会写y = 42。根据这一观察,人们现在可以争辩说,之前的x = 42是一种法律观察。然而,最初的假设是凭空捏造被禁止的事情,x = y = 0是唯一合法的结果。

发生之前关系的定义仅适用于明确同步的程序,并且不会禁止假设的循环推理。因此,需要凭空限制。这当然是学术性的,但JMM是一个学术模型,仍然需要定义这个限制。

因此,在任何一个图中都没有值xy可以采用的比赛条件,即没有比赛条件,x = y = 0是唯一可能的观察。因此,尽管没有volatile

,但两个示例都正确同步

答案 1 :(得分:0)

图6

之前发生的模型仅基于同步并且边缘之前发生。 JLS提供了发生在之前一致执行的示例:

r1 = x;  // sees write of x = 1
y = 1;
r2 = y;  // sees write of y = 1
x = 1;

在这个例子中,这些值出现在空中"它是发生 - 在之前一致但是打破了因果关系要求(没有顺序一致的执行可以产生这个结果)。因此,这样的执行不是合法的执行。

图7

r1 === r2 == 42 是有效的结果。

没有同步,但唯一有效的结果是所有值都为0,因为没有为变量分配其他值。例如,在y = r1中,r1的默认值(0)或值x(0) - 在这两种情况下y都为0。 / p>

作为旁注,您应该阅读Chapter 17 of the JLS而不是原始的JSR。