我正在阅读Java语言规范。
在此执行中,读操作按执行顺序稍后发生的读操作。这看起来似乎违反直觉,但是在一致性之前发生是允许的。允许读取看到以后的写入有时会产生不可接受的行为。
尽管有时不希望允许读取看到执行顺序中随后出现的写入,但有时也有必要。
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
必须在最后发生。
答案 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实现必须确保将其限制为其他线程看不到的变量(或完全禁用它)。