BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #56311同步于 2017/5/20
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

java happen—before 的问题

hyx2011
2017/5/20镜像同步4 回复
看到 java 的 happen-before 的规则,里面有一条是传递性,也就是 如果操作A happen—before操作B,操作B happen—before操作C,那么可以得出A happen—before操作C。这里有点疑惑,如果没有这种传递性的规定,感觉对实际系统同样没有影响啊?如果去掉这一条规则会出现什么样的问题?
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
ml3615556机器人#1 · 2017/5/20
这是对Java多线程编程模型的描述,去掉传递性类似与数学中比较符号失去传递性一样
hyx2011机器人#2 · 2017/5/20
但是失去传递性对整体没啥影响吧 【 在 ml3615556 (Andy) 的大作中提到: 】 : 这是对Java多线程编程模型的描述,去掉传递性类似与数学中比较符号失去传递性一样
fengzhiya机器人#3 · 2017/5/21
不同顺序的操作,怎么会对结果没影响呢?最简单的比如赋值操作,不同顺序,对结果影响挺大啊。
nuanyangyang机器人#4 · 2017/5/21
这是对语义的规定。比如: 有两个成员变量x,y,其中y是volatile的。初始值都是0. int x = 0; volatile y = 0; 线程1先写x,后写y。 Thread thread1 = new Thread(() -> { x = 1; y = 2; }); 线程2先读y,后读x。如果读到y==2,就打印读到的x的值,如果y不是2就不打印: Thread thread2 = new Thread(() -> { int yy = y; int xx = x; if (yy == 2) { System.out.println(xx); } }); 请问线程2如果读到y==2,是否一定也能读到x==1? 答案是:一定。只要读到y==2,一定读到x==1。 但是要解释为什么,就要利用happen-before的传递性了。下面用简写: x po y: x comes before y in the program order x sw y: x is synchronized with y x hb y: x happens before y 同一个线程里的动作符合程序顺序。所以,thread1里,“x=1” po “y=2“。同样,thread2里,“yy=y” po “xx=x”。 两个线程之间,thread2里对volatile变量y的读,读到了thread1里对y的写写入的值(即读到了2),那么就有“y=2” sw “yy=y“,其中前者来自thread1,后者来自thread2。 Java Memory Model里,happens-before关系是program order和synchronized with的并集。即所有的po和sw都是hb。于是有: “x=1” hb “y=2” “y=2” hb “yy=y” “yy=y” hb “xx=x” 又因为hb具有传递性,所以“x=1” hb “xx=x”。又因为除此之外没有对x的写操作,所以thread2里那个“xx=x”一定能读到1。 如果hb不具有传递性,那么thread1里的“x=1”和thread2里的“xx=x”之间就没有hb关系,也就不能保证thread2一定能读到x=1了。这样的话volatile产生的sw关系就起不到同步作用了。 【 在 hyx2011 的大作中提到: 】 : 看到 java 的 happen-before 的规则,里面有一条是传递性,也就是 如果操作A happen—before操作B,操作B happen—before操作C,那么可以得出A happen—before操作C。这里有点疑惑,如果没有这种传递性的规定,感觉对实际系统同样没有影响啊?如果去掉这一条规则会出现什么样的问题?