关于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)
}