指令重排序举的例子的疑问
来源:12-4 相关概念

扶摇羊角
2021-02-17
public class OutOfOrderExecution {
private static int x = 0, y = 0;
private static int a = 0, b = 0;
private static CountDownLatch countDownLatch = new CountDownLatch(1);
public static void main(String[] args) throws InterruptedException {
int i = 0;
for (; ; ) {
i++;
x = 0;
y = 0;
a = 0;
b = 0;
Thread one = new Thread(() -> {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
a = 1;
x = b;
});
Thread two = new Thread(() -> {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
b = 1;
y = a;
});
two.start();
one.start();
countDownLatch.countDown();
one.join();
two.join();
System.out.println("第" + i + "次 x = " + x + ", y = " + y);
if (x == 0 && y == 0) {
break;
}
}
}
}
对于课程中关于重排序举的这个例子,由于是在两个线程中对于共享变量的操作,这种操作是线程不安全的,即使当两个线程运行完成,x = 1,y = 1,那么这时主存中的x和y还未得到更新,则会出现x = 0,y = 0的情况,我的理解是这种并非发生了指令重排序。
麻烦解答一下?
写回答
1回答
-
悟空
2021-02-17
从现象上看,无法判断是未更新还是发生了重排序,因为现象都是一样的。
但是happens-before的规则之一:join()规则:如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作happens-before于线程A从ThreadB.join()操作成功返回。
所以主内存一定能看到子线程执行的结果。
00
相似问题