关于系统重排序对多线程的影响案例复现
最近一直在看《Java 并发编程的艺术》这本书,有一说一,书是真的不错。
但是在 P29 讲到重排序对多线程的影响这个小结时,实例代码逻辑上确实说的过去,但是我在 IDEA 一直无法复现,没有重排序的现象出现。一切以事实说话,到底在多线程中有没有重排序?或者直接说操作系统里面有没有对指令重排序。于是我找到了一个多线程新的案例这是原地址
public class ThreadReorderTest {
/** 设置初始值 */
static class State {
int a = 0;
int b = 0;
int c = 0;
}
public static void main(String[] args) {
for (int i = 0; i < 1000_000; i++) {
final State state = new State();
// a = 0, b = 0, c = 0
// Write values 写入数据进程
new Thread(() -> {
state.a = 1;
// a = 1, b = 0, c = 0
state.b = 1;
// a = 1, b = 1, c = 0
state.c = state.a + 1;
// a = 1, b = 1, c = 2
}).start();
// Read values - this should never happen, right? 读入数据进程,重排序真的会发生吗
new Thread(() -> {
// copy in reverse order so if we see some invalid state we know this is caused by reordering and not by a race condition in reads/writes
// we don't know if the reordered statements are the writes or reads (we will se it is writes later)
int tmpC = state.c;
int tmpB = state.b;
int tmpA = state.a;
if (tmpB == 1 && tmpA == 0) {
System.out.println("Hey wtf!! b == 1 && a == 0");
}
if (tmpC == 2 && tmpB == 0) {
System.out.println("Hey wtf!! c == 2 && b == 0");
}
if (tmpC == 2 && tmpA == 0) {
System.out.println("Hey wtf!! c == 2 && a == 0");
}
}).start();
}
System.out.println("done");
}
}
运行了大概十几次,终于出现了重排结果:Hey wtf!! c == 2 && b == 0
如果没有重排,按照两个线程的顺序,不会出现任何 Hey wtf!! 字样的打印结果。说明发生了如下图的重排