使用不可變Java記錄Record來避免多執行緒併發錯誤 - foojay

banq發表於2021-06-10

在多執行緒 Java 應用程式中,任何執行緒都可以更改物件的狀態。Java 語言規範中的Java 記憶體模型指定了一個執行緒所做的準確更新何時對其他執行緒可見。這是專業 Java 開發人員每天處理的最大問題之一。Java 記錄record是不可變的,如果物件在構造後其狀態不能改變,則該物件被認為是不可變的。記錄的不可變特性消除了它在多執行緒環境中使用的問題。
記錄元件是最終的,這意味著我們不能更改分配後的記錄元件。雖然我們可以改變記錄元件的欄位,但沒有限制,它使記錄淺不可變。讓我們用一個例子來看看。

public class EmployeeTest {

    public static void main(String[] args) {

        List<Integer> integerList = new ArrayList<>();
        integerList.add(1);
        IntegerListRecord integerListRecord = new IntegerListRecord(integerList);
        System.out.println(integerListRecord.getListSize());

        integerList.add(2);
        System.out.println(integerListRecord.getListSize());

    }

}

record IntegerListRecord(List<Integer> integerList) {
    int getListSize() {
        return integerList.size();
    }
}


在這個例子中,我們建立了一個整數列表(integerList),向其中新增了一個元素,並用它初始化了記錄類。呼叫record類的getListSize方法結果為1。現在我們在integerList中再增加一個元素,呼叫getListSize結果為2。這裡我們沒有改變record元件(integerList)而是更新了record元件的欄位,它沒有任何限制。這就是我們稱記錄為淺不可變的原因。
 

記錄Record不可變特點:

  • 記錄類是隱式最終的,不能是抽象的,這樣我們就不能建立記錄類的子類。
  • 所有記錄類預設擴充套件 java.lang.Record 所以不能擴充套件任何其他類。
  • 記錄類不能宣告例項欄位。
  • 我們不能為記錄元件分配一個新值,因為它們是隱式最終的。這些是在規範建構函式中初始化記錄時分配的值。
  • 只有規範建構函式可以更新記錄元件,在初始化記錄時呼叫。對於其他型別的建構函式,在建構函式主體中分配任何記錄元件都會導致編譯時錯誤。
  • 記錄元件在反射中有特定的處理 欄位API. 這種處理就像隱藏類。您可以閱讀有關隱藏課程的更多資訊這裡.

 

結論
記錄可幫助您刪除重複且容易出錯的程式碼,並提高開發人員的工作效率。不變性功能使其遠離併發錯誤。使用這樣的語言功能將使您成為每個人都想僱用的優秀開發人員。

相關文章