當我們寫乙個單執行緒程式時,總以為計算機會一行行地執行**,然而事實並非如此。
重排序指的是編譯器、處理器在不改變程式執行結果的前提下,重新排列指令的執行順序,以達到最佳的執行效率。
重排序分為:編譯器重排序 和 處理器重排序。
編譯器和處理器並不會隨意的改變指令的執行順序,因為有些指令之間是有依賴關係的,若改變了他們的執行順序,就會出現錯誤的結果。
因此,編譯器和處理器只會對沒有依賴關係的指令進行重排序。
資料依賴:若相鄰的兩條指令訪問同乙個變數,並且其中有一條指令執行寫操作,那麼這樣的兩條指令之間存在資料依賴。對於有資料依賴關係的指令,不會發生重排序。
資料依賴關係總結一下為以下三種情況:
指令示例
讀後寫a=b;b=1;
寫後寫a=1;a=2;
寫後讀a=1;b=a;
在單執行緒開發中,程式設計師不需要知道指令是如何重排序的,只要簡單地認為指令是按照順序依次執行的即可。這就是as-if-serial的語義,即:貌似是序列的。
Java 記憶體模型的基礎(二) 重排序
如果兩個操作訪問同乙個變數,且兩個操作中有乙個為寫操作,此時這兩個操作就存在資料依賴性。資料依賴分為以下三種情況 名稱 示例 說 明 寫後讀a 1 b 2 寫乙個變數後,再讀這個位置 寫後寫a 1 a 2 寫乙個變數後,再寫這個變數 讀後寫a b b 1 讀乙個變數之後,再寫這個變數 上述三種情況,...
深入理解Java記憶體模型(二) 重排序
如果兩個操作訪問同乙個變數,且這兩個操作中有乙個為寫操作,此時這兩個操作之間就存在資料依賴性。資料依賴分下列三種型別 上面三種情況,只要重排序兩個操作的執行順序,程式的執行結果將會被改變。前面提到過,編譯器和處理器可能會對操作做重排序。編譯器和處理器在重排序時,會遵守資料依賴性,編譯器和處理器不會改...
深入理解java記憶體模型(二)重排序
資料依賴性 如果兩個操作訪問同乙個變數,且這兩個操作中有乙個為寫操作,此時這兩個操作之間就存在資料依賴性。資料依賴分下列三種型別 名稱 示例 說明 寫後讀 a 1 b a 寫乙個變數之後,再讀這個位置。寫後寫 a 1 a 2 寫乙個變數之後,再寫這個變數。讀後寫 a b b 1 讀乙個變數之後,再寫...