代码之家  ›  专栏  ›  技术社区  ›  Dean Xu

Java规范:在执行顺序中读取稍后出现的写入

  •  2
  • Dean Xu  · 技术社区  · 6 年前

    我现在正在阅读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 . 根据定义 execution order ,没有人可以重新订购

    r1 = x; // write
    

    if (r1 != 0) // read
    

    以便 y = 1 一定是最后一次。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Holger    6 年前

    实例

    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代码的。如果我们只有 以前发生过 一致性。但是Java还禁止使用超薄空气值β。因此,支持这种推测性执行的体系结构的JVM实现必须确保它仅限于其他线程看不到的变量(或完全禁用它)。