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

Mar*_*nik 5 java

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

内存模型确定可以在程序中的每个点读取哪些值.隔离中每个线程的操作必须遵循该线程的语义,除了每次读取所看到的值由内存模型确定.

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

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

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

2.发生 - 在一致性之前:

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

这基本上排除了它观察到的写入之前发生的读取.另一个条款只是一个完整性条款,它可以防止某些人v看到之前写的那篇内容,v然后又写了一篇同样的内容v.

我无法保证可以正确地观察到写入,只能限制对写入的内容.

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

ass*_*ias 4

让我们使用:

\n\n
class MyClass {\n    private static int i = 0;\n\n    public static void main(String[] args) {\n        i = 3; //w\n        System.out.println(i); //r\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  • 当且仅当所有顺序一致的执行都没有数据争用时,程序才能正确同步。
  • \n
  • 如果程序正确同步,则该程序的所有执行将显示为顺序一致 (\xc2\xa717.4.3)。
  • \n
  • 当程序包含两个不按先发生关系排序的冲突访问 (\xc2\xa717.4.1) 时,称其包含数据争用。

    \n\n

    您的程序是单线程的
    \n=> 我们从程序顺序约束中得到 hb(w,r)
    \n=> 它已正确同步
    \n=> 程序的所有执行将显示为顺序一致。
    \n=> 它将打印 3

  • \n
\n

  • @MarkoTopolnik 你今天很容易放弃;-) (2认同)
  • 是的,与上次相比发生了很大的变化……我能说什么,这听起来不错,感觉不错,在盯着它看了几分钟之后(包括过去两周对 JLS 的所有盯着),我想这个论点无可挑剔。我错过了与“看起来顺序一致”的联系,它本身就带来了硬性保证。 (2认同)