5

考虑一个简单的单线程 Java 程序执行,不涉及同步操作,只是简单地读取和写入实例变量。简单地忽略所有写入的实现似乎符合 Java 内存规范。首先,来自§17.4的适用一般性陈述:

内存模型决定了程序中每个点可以读取哪些值。每个单独的线程的操作必须按照该线程的语义进行操作,但每次读取看到的值由内存模型确定。

相关限制如下(§17.4.5):

1. 程序顺序引发的happens-before顺序:

如果 x 和 y 是同一线程的操作,并且 x 在程序顺序中位于 y 之前,则为 hb(x, y)。

2.happens-before一致性:

如果对于 A 中的所有读取 r,一组动作 A 在发生之前是一致的,其中 W(r) 是 r 看到的写入动作,但不是 hb(r, W(r)) 或存在在 A 中存在写入 w 使得 wv = rv 和 hb(W(r), w) 和 hb(w, r)。

这基本上排除了在它观察到的写入之前发生读取。另一个条款只是一个理智的条款,它阻止了一些人v看到之前写v的同时又写了同样的内容v

我找不到任何保证可以肯定地观察到写入,只有对写入内容的限制可能不会被观察到。

我在这里想念什么?JVM真的有可能忽略这样一个微不足道的保证吗?

4

1 回答 1

3

让我们使用:

class MyClass {
    private static int i = 0;

    public static void main(String[] args) {
        i = 3; //w
        System.out.println(i); //r
    }
}
  • 当且仅当所有顺序一致的执行都没有数据竞争时,程序才能正确同步。
  • 如果程序正确同步,则程序的所有执行都将显示为顺序一致(第 17.4.3 节)。
  • 当一个程序包含两个冲突的访问(第 17.4.1 节)时,这些访问没有按发生前的关系排序,则称为包含数据竞争。

    您的程序是单线程的
    => 我们有来自程序顺序约束的 hb(w,r)
    => 它是正确同步
    的 => 程序的所有执行将看起来是顺序一致的。
    => 它将打印 3

于 2012-08-29T10:09:48.693 回答