关于Java发生之前的关系,需要澄清

关于Java发生之前的关系,需要澄清,java,multithreading,Java,Multithreading,据说: 两个动作可以由“发生在之前”关系排序。如果一个动作发生在另一个动作之前,那么第一个动作对第二个动作可见并在第二个动作之前排序 还有人说: 例如,处于数据竞争中的一个线程中的写操作与另一个线程中的读操作可能会出现顺序错误 这是否意味着如果hb(r,w),那么r必须在w之前,或者如果r在之前,那么发生在关系发生之前?hb(r,w)意味着r在w之前执行,并且w可以看到r的结果 在读/写操作的情况下,您通常关心有一个hb(w,r),并希望确保读操作看到写操作的结果 使用同步块的示例: 块w(写入

据说:

两个动作可以由“发生在之前”关系排序。如果一个动作发生在另一个动作之前,那么第一个动作对第二个动作可见并在第二个动作之前排序

还有人说:

例如,处于数据竞争中的一个线程中的写操作与另一个线程中的读操作可能会出现顺序错误

这是否意味着如果
hb(r,w)
,那么
r
必须在
w
之前,或者如果
r
在之前,那么发生在关系发生之前?

hb(r,w)
意味着
r
w
之前执行,并且
w
可以看到
r
的结果

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

使用同步块的示例:

w
(写入):

r
(读取):

w
r
在同一个监视器上同步,因此这两个监视器之间存在“先发生后发生”关系

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

如果没有同步块,则不再存在before关系,即使在
r
之前执行
w
(从挂钟的角度来看),
r
可能会打印一个过时的
变量值

如果没有“先发生后发生”关系,甚至可能会出现在
r
之后执行
w
的情况,即使您的程序的编写方式不应如此(即JVM可能已对操作重新排序)

Oracle Java语言架构师Brian Goetz在中给出了一个非常好的例子,说明了如果没有关系,事情会变得多么奇怪。

此链接可能会有所帮助。
synchronized (lock) { //lock is a final object
    aVariable = something;
}
synchronized (lock) { //the same final object
    System.out.println(aVariable)
}