Java规范:读后写按执行顺序发生

时间:2018-08-09 00:57:51

标签: java jvm memory-model language-specifications

我正在阅读Java语言规范。

§17.4.5-1

  

在此执行中,读操作按执行顺序稍后发生的读操作。这看起来似乎违反直觉,但是在一致性之前发生是允许的。允许读取看到以后的写入有时会产生不可接受的行为。

§17.4.8-1

  

尽管有时不希望允许读取看到执行顺序中随后出现的写入,但有时也有必要。

17.4.8-1也给出了一个奇怪的例子。

为什么reads see writes come later有可能?

如果确实有可能,如何在Java代码中重现它?

编辑

这不是重复的问题。这个问题刚刚问了17.4.5-1,我可以理解17.4.5-1,因为编译器可能会对它们重新排序。但是17.4.8-1呢?它位于Executions and Causality Requirements下。根据{{​​1}}的定义,没有人可以重新排序

execution order

r1 = x; // write

这样if (r1 != 0) // read 必须在最后发生。

1 个答案:

答案 0 :(得分:2)

示例

Table 17.4.8-A

      Thread 1                  Thread 2
r1 = x;                    r2 = y;
if (r1 != 0) y = 1;        if (r2 != 0) x = 1;
在具有投机性执行的体系结构上,

是可能的。因此,当从主存储器请求的值尚未到达时,CPU会遇到条件分支,并决定执行条件代码并在条件不满足的情况下回滚它。

当值到达CPU内核时,它是另一个线程写入的值,因此条件得以满足并且更改得以保留。

您不能在Java代码中重现此内容,因为该规范继续说明Java代码不允许这种情况。如果我们只有 happens-before 一致性,这是允许的例子。但是Java另外还禁止“凭空赚钱”。因此,支持这种推测执行的体系结构的JVM实现必须确保将其限制为其他线程看不到的变量(或完全禁用它)。