Java併發 final域的記憶體語義

2021-08-28 10:01:23 字數 592 閱讀 2743

對於final域,編譯器和處理器都要遵守兩個重排序規則

1)在建構函式內對乙個final域的寫入,與隨後把這個被構造物件的引用賦值給乙個引用變數,這兩個操作之間不能重排序。

2)初次讀乙個包含final域的物件的引用,與隨後初次讀這個final域,這兩個操作之間不能重排。

寫final域的重排序規則禁止把final域的寫重排序到建構函式之外。

1)jmm禁止編譯器把final域的寫重排序到建構函式之外

2)編譯器會在final域的寫之後,建構函式return之前,插入乙個storestore屏障。這個屏障禁止處理器把final域的寫重排序到建構函式之外。

讀final域的重排序規則,在乙個執行緒中,初次讀物件引用與初次讀該物件包含的final域,jmm禁止處理器重排序這兩個規則,編譯器會在讀final域操作的前面插入乙個loadload屏障。 

為什麼final引用不能從建構函式內「溢位」:在前面寫final域的重排序規則可以確保:在引用變數為任意執行緒可見之前,該引用變數指向的物件的final域已經在建構函式中被正確初始化過了。其實,要得到這個效果,還需要乙個保證:在建構函式內部,不能讓這個被構造物件的引用為其他執行緒所見,也就是物件引用不能在建構函式中溢位。

final域的記憶體語義

對於final域,編譯器和處理器要遵守兩個重排序規則。1,在建構函式內對乙個final域的寫入,與隨後把這個被構造物件的引用賦值給乙個引用變數,這兩個操作之間不能重排序。2,初次讀入乙個包含final域的物件的引用,與隨後初次讀這個final域,這兩個操作之間不能重排序。寫final域的重排序規則 ...

Java記憶體模型總結 final

1 final域的重排序規則 2 寫final域的重排序規則 寫final域的重排序規則確保 在物件引用為任意執行緒可用之前,物件的final域已經被正確初始化,普通域不具有這個保障。3 讀final域的重排序規則 讀final域的重排序規則保證 在讀乙個final域之前,一定先讀該final域的物...

Java 併發 記憶體模型

源 中的指令順序和實際執行時的指令順序可能是不同的,編譯器出於優化的目的,會對指令進行 重排序 會採用亂序或並行等方式來執行指令,它只要滿足乙個條件即可 程式的最終結果與在嚴格序列環境中執行的結果相同 在這種情形下,如果另乙個執行緒坐在那觀察某個執行過程中的執行緒,會發現該執行緒的執行過程是不可 的...