Java内存模型是否保证了线程内写入的可见性?

时间:2012-08-29 09:54:52

标签: java

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

  

内存模型确定程序中每个点可以读取的值。隔离中每个线程的操作必须表现为受该线程语义的控制,但每次读取所看到的值都由内存模型决定。

相关的限制因素如下(§17.4.5):

1。在由程序顺序引起的排序之前发生:

  

如果x和y是同一个线程的动作,并且x在程序顺序中位于y之前,那么hb(x,y)。

2。发生在一致性之前:

  

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

这基本上排除了发生之前它所观察到的写入。另一个条款只是一个完整性条款,它阻止某些v看到之前写的那个v,同时又写了同一个v

我无法保证能够正确地观察到写入,只能对可能无法观察到的写入进行限制。

我在这里缺少什么? JVM是否真的可以省略这样一个微不足道的保证?

1 个答案:

答案 0 :(得分: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

相关问题