为了账号安全,请及时绑定邮箱和手机立即绑定

在一致之前如何理解发生

在一致之前如何理解发生

三国纷争 2019-12-04 15:12:18
在JLS的第17章中,它引入了一个概念:一致性之前发生。如果对于A中的所有读取r,其中W(r)是r看到的写动作,则不是发生hb(r,W(r))或在A中存在一个写w,使得wv = rv和hb(W(r),w)和hb(w,r)”以我的理解,它等同于以下词语:...,在这种情况下,...和...都不所以我的前两个问题是:我的理解正确吗?“ wv = rv”是什么意思?它还给出了一个示例:17.4.5-1Thread 1 Thread 2B = 1; A = 2; r2 = A; r1 = B; 按照第一个执行顺序:1: B = 1;3: A = 2;2: r2 = A;  // sees initial write of 04: r1 = B;  // sees initial write of 0该命令本身已经告诉我们两个线程是交替执行的,所以我的第三个问题是:左数是什么意思?以我的理解,r2和r1都能看到初始写入0的原因是A和B都不是易失字段。所以我的第四个问题是:我的理解是否正确?按照第二个执行顺序:1: r2 = A;  // sees write of A = 23: r1 = B;  // sees write of B = 12: B = 1;4: A = 2;根据一致性之前发生的定义,不难理解这种执行顺序是一致性之前发生的(如果我的第一理解是正确的)。所以我的第五和第六个问题是:现实世界中是否存在这种情况(读后看写)?如果可以,您能给我一个真实的例子吗?
查看完整描述

3 回答

?
缥缈止盈

TA贡献2041条经验 获得超4个赞

Java内存模型定义了程序中所有动作的部分顺序,这称为巧合-before
为了确保线程Y能够看到动作的副作用XX无论是否发生在不同的线程中都无关紧要),在和之间定义了事前发生的关系。 如果不存在这种关系,则JVM可能会重新排序程序的操作。 现在,如果一个变量被多个线程共享和访问,并且(至少)一个线程写入了一个变量(如果读写未按关系发生前的顺序进行排序),那么您将进行数据竞争。XY


在正确的程序中,没有数据争用。
示例是2个线程AB在锁上同步X
Thread A获取锁(现在Thread B被锁定)并执行写操作,然后释放lock X。现在Thread B获取锁X和自所有的动作Thread A都完成释放之前锁定X,他们之前订购的行动,Thread B收购了锁X 线A(也可见Thread B)。
请注意,这发生在同一锁上同步操作。还有就是没有同步线程之间的关系之前发生在不同的锁上

查看完整回答
反对 回复 2019-12-04
?
Cats萌萌

TA贡献1805条经验 获得超9个赞

本质上是正确的。这样做的主要目的是:除非您使用某种形式的同步,否则不能保证按照程序顺序执行写操作后发生的读操作将看到该写操作的效果,因为语句可能已被重新定义。


在现实世界中是否存在这种情况(读后见写)?如果可以,您能给我一个真实的例子吗?


从挂钟的角度来看,很明显,读取看不到尚未发生的写入的效果。


从程序顺序的角度来看,由于如果没有适当的同步(关系之前发生),则可以对语句进行重新排序,因此在程序写入之前进行的读取可能会在执行期间看到该写入的效果,因为它已被执行由JVM写入之后。


查看完整回答
反对 回复 2019-12-04
  • 3 回答
  • 0 关注
  • 362 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信