3 回答

TA贡献2041条经验 获得超4个赞
Java内存模型定义了程序中所有动作的部分顺序,这称为巧合-before。
为了确保线程Y
能够看到动作的副作用X
(X
无论是否发生在不同的线程中都无关紧要),在和之间定义了事前发生的关系。 如果不存在这种关系,则JVM可能会重新排序程序的操作。 现在,如果一个变量被多个线程共享和访问,并且(至少)一个线程写入了一个变量(如果读写未按关系发生前的顺序进行排序),那么您将进行数据竞争。X
Y
在正确的程序中,没有数据争用。
示例是2个线程A
并B
在锁上同步X
。Thread A
获取锁(现在Thread B
被锁定)并执行写操作,然后释放lock X
。现在Thread B
获取锁X
和自所有的动作Thread A
都完成释放之前锁定X
,他们之前订购的行动,Thread B
收购了锁X
后线A
(也可见Thread B
)。
请注意,这发生在同一锁上同步的操作上。还有就是没有同步线程之间的关系之前发生在不同的锁上

TA贡献1805条经验 获得超9个赞
本质上是正确的。这样做的主要目的是:除非您使用某种形式的同步,否则不能保证按照程序顺序执行写操作后发生的读操作将看到该写操作的效果,因为语句可能已被重新定义。
在现实世界中是否存在这种情况(读后见写)?如果可以,您能给我一个真实的例子吗?
从挂钟的角度来看,很明显,读取看不到尚未发生的写入的效果。
从程序顺序的角度来看,由于如果没有适当的同步(关系之前发生),则可以对语句进行重新排序,因此在程序写入之前进行的读取可能会在执行期间看到该写入的效果,因为它已被执行由JVM写入之后。
添加回答
举报