1. 程式人生 > 其它 >關於系統重排序對多執行緒的影響案例復現

關於系統重排序對多執行緒的影響案例復現

最近一直在看《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!! 字樣的列印結果。說明發生了如下圖的重排