HappenBefore指令重排

HappenBefore

·你寫的代碼很可能根本沒按你期望的順序執行,因爲編譯器和CPU會嘗試重排指令使得代碼更快地運行。
·在虛擬機層面,爲了儘可能減少內存操作速度遠慢於CPU運行速度所帶來的CPU空置的影響,虛擬機會按照自己的一些規則將程序編寫順序打亂——即寫在後面的代碼在時間順序上可能會先執行,而寫在前面的代碼會後執行——以儘可能充分地利用CPU。
·在硬件層面,CPU會將接受到的一批指令按照其規則重排,同樣是基於CPU速度比緩存速度快的原因,和上一點的目的類似,只是硬件處理的話,每次只能在接收到的有限指令範圍內重排,而虛擬機可以在更大層面、更多指令範圍內重排。

public class HappenBefore {
    private static int a = 0;
    private static boolean flag = false;

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 100; i++) {
            a = 0;
            flag = false;
            Thread t1 = new Thread(()-> {
                flag = true;
            });

            Thread t2 = new Thread(()-> {
                if(flag)
                    a += 1;
                //指令重排
                if(a == 0)
                    System.out.println("a is --> " + a);
            });
            t1.start();
            t2.start();

            t1.join();
            t2.join();
        }
    }
}

實驗N次後得到如下結果
在這裏插入圖片描述
最後一次的結果顯然是不正常的,但其它輸出爲0的其實也不正常,根據順序結構,我們的代碼應該會先執行a+1的操作,然後再執行下面的代碼,這個時候a不應該爲0,也就是不應該打印。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章