Loading

关于系统重排序对多线程的影响案例复现

最近一直在看《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!! 字样的打印结果。说明发生了如下图的重排

posted @ 2022-01-15 21:59  归思君  阅读(107)  评论(0编辑  收藏  举报