关于 Java 的指令排序问题

2023-08-11 10:54:41 +08:00
 memedahui
我看到的资料说英特尔 x86 的芯片因为没有失效队列,所以在某些情况不会乱序,但是我的电脑用的是英特尔的 i5-12400,使用了 org.openjdk.jcstress 测试还是出现了乱序,理论上 arm 上面才会乱序,我要怎么复现不乱序的情况(不能修改代码,不使用屏障)?哪位知道的求解
代码如下
@JCStressTest
@Outcome(id = "0, 0", expect = Expect.ACCEPTABLE, desc = "OK")
@Outcome(id = "0, 1", expect = Expect.ACCEPTABLE, desc = "OK")
@Outcome(id = "1, 0", expect = Expect.ACCEPTABLE_INTERESTING, desc = "NOT OK")
@Outcome(id = "1, 1", expect = Expect.ACCEPTABLE, desc = "OK")
@State
public class Demo {

int a;
int b;

@Actor
public void actor1() {
a = 1;
b = 1;
}

@Actor
public void actor2(II_Result r) {
r.r1 = b;
r.r2 = a;
}
}
结果如下
0, 0
1,418,619 ACCEPTABLE OK
0, 1
12,299 ACCEPTABLE OK
1, 0
858 ACCEPTABLE_INTERESTING NOT OK
1, 1
128,197,735 ACCEPTABLE OK

1, 0 这种情况是不应出现的,还是出现了 858 次
1000 次点击
所在节点    Java
1 条回复
letianqiu
2023-08-14 14:25:38 +08:00
Java 的 memory model 和 micro-architecture 的 memory model 是不同的。x86 是 total store ordering ,arm 是 weak memory order 。但是对于 Java 来说,jvm 实现保证了在 x86 和 arm 上都符合 Java Memory Model 的 spec 。回到你的问题,你这段代码里,a 和 b 既不是 volatile 的,同时 read/write 也没有用 atomic/lock ,所以不存在 happens-before 的关系。四种情况都是可能的。

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

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

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

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

© 2021 V2EX