Happens-Before 关系中的微妙时刻

Subtle moments in Happens-Before relationship

这个问题涉及JMM: https://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf

能否解释一下 JMM 规范中的以下表达式(这是第 13 页的第 5 节):

More specifically, if two actions share a happens-before relationship, they do not necessarily have to appear to have happened in that order to any code with which they do not share a happens- before relationship. Writes in one thread that are in a data race with reads in another thread may, for example, appear to occur out of order to those reads.

如果可能,请提供反映此问题的执行跟踪。

您引用的段落之前的段落已经指出,动作 a 与动作 b 处于先行关系这一事实并不意味着 a 确实在 b 之前执行。例如,在代码片段

x = 10;
y = 20;

这两个写操作是happens-before关系,因为它们发生在同一个线程中。但是,它们实际上可能会被交换(由编译器、JVM 甚至处理器),因为这种交换无法从线程本身内部观察到。

但是,它可以被另一个线程观察到(这是 Java 内存模型特别允许的)。因此,读取这两个变量的另一个线程,在没有某种形式的同步的情况下,可能会观察到 y 在 x 更改为 10 之前更改为 20。(没有同步确保写入与读取在数据竞争中其他线程。)