3

JLS中说:

两个动作可以通过happens-before关系排序。如果一个动作发生在另一个动作之前,那么第一个动作对第二个动作可见并在第二个动作之前排序。

也有说:

例如,一个线程中的写入与另一个线程中的读取处于数据竞争中,这些读取可能会出现乱序。

这是否意味着 if ,hb(r, w) thenr一定在w r

4

1 回答 1

6

hb(r, w)表示在AND可以看到结果r之前执行。wwr

在读/写操作的情况下,您通常关心有一个hb(w, r)并希望确保读取看到写入的结果。

使用同步块的示例:

w(写入):

synchronized (lock) { //lock is a final object
    aVariable = something;
}

r(读取):

synchronized (lock) { //the same final object
    System.out.println(aVariable)
}

w并且r在同一个监视器上同步,因此两者之间存在发生之前的关系。

假设w在 之前执行r,这意味着我们有hb(w, r),那么 JMM 保证r将打印 的最新值aVariable

如果没有同步块,就不再存在之前发生的关系,即使在w之前执行r(从挂钟的角度来看),r也可能会打印aVariable.

如果没有发生之前的关系,即使您的程序以不应该的方式编写(即 JVM 可能已重新排序操作) ,它甚至可能w是在之后执行的情况。r

JLS - Example 17.4-1中给出了一个很好的例子,说明如果没有发生之前的关系,事情会变得多么奇怪。

于 2012-07-13T11:20:49.123 回答