关于指令重排序有个问题不明白,求大佬指点

2021-01-18 21:18:54 +08:00
 svt

《 JAVA 并发编程的艺术》一书中说指令重排序可能会改变多线程程序的执行结果。举的例子如下:

class test { private int a = 0; private boolean flag = false;

public void change() {
    a = 1;
    flag = true;
}

public void sysout() {
    while (flag) {
        System.out.println(a);
    }
}

}

书中说以上程序在多线程时,输出的结果不一定是 1,有可能是 0 ; 但是我自己尝试了多次也未复现出这种情况,因此非常疑问这个情况真的可以复现出来吗?这个指令重排序到底说的真的假的呀?如果有复现出来的同学可以发个程序执行结果的图看下嘛?

3143 次点击
所在节点    程序员
25 条回复
Still4
2021-01-19 13:05:09 +08:00
你这个例子没问题,指令重排会保证最终执行结果跟预期一样,但是不保证顺序,也就是说 change 方法执行完以后,a 一定=1,flag 一定=true,但是谁先谁后不一定

这样一来,多线程环境下,监听线程读取到 flag 变成 true 的时候,a 的值有可能=0 有可能=1,不能按编码顺序去理解
icyalala
2021-01-19 13:38:33 +08:00
单说指令的话:
一个是编译器在编译时,指令可能会被重新排序,
一个是 CPU 在 Out of Order 执行指令时,也可能会被重排。

要说 Memory Model 那涉及到的东西就更多了。
zhch602
2021-01-19 18:57:17 +08:00
@mxalbert1996 重排序并不只是 JIT 的事,CPU 指令流水线执行指令的时候也会指令重排的
fuse
2021-01-23 11:51:44 +08:00
@lewis89 总结起来不就是异步嘛
lewis89
2021-01-23 12:08:39 +08:00
@fuse #24 但是不能影响单线程的串行化语义

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/746080

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX