簡體   English   中英

object 初始化在 Java 中是原子的嗎?

[英]Is object initialization atomic in Java?

我知道myObject1 = myObject2是原子的,但是下面的代碼行是原子的嗎?

Object obj1 = new Object();

它實際上可以在初始化引用的中間暫停嗎?

它不是原子的。 沒有什么能阻止你在 Object 構造函數中sleep ,或者無限循環,或者在構造函數中拋出異常。

注意:盡管可能,但這些都是反模式,不推薦使用。

這條線不是原子的。 發生了兩件事:首先,創建了新的Object (通常不是原子的),然后將這個 object 的引用分配給變量obj1 比如說,由Thread1執行的行和Thread2觀察變量的 state 。 Thread2可以觀察到三種狀態(為簡單起見,假設 object 創建本身是原子的),

  1. obj1 == null ,未創建 object
  2. obj1 == null , object 已創建,但對它的引用尚未分配給變量
  3. obj1 != null ,該行已完全執行

原子性表明Thread2可能僅觀察 state 1 和 3,但必須強制執行。 使其原子化的一種方法是通過同步(在此示例中, obj1是 class 字段):

public synchronized Object getObj() {
    if (obj1 == null)
        obj1 = new Object();

    return obj1;
}

第一個調用此方法的線程將初始化該字段,進一步調用將簡單地返回該變量。 由於互斥,創建null后,線程不可能觀察到obj1中的null,因為不同線程的方法調用不能重疊。

引用分配是原子的。 沒有條件可以部分分配引用本身(這顯然會導致 VM 有時崩潰)。 它將是 null 或不為空。 在分配引用之前 object 的構造不是原子的,但是在構造過程完成之前,您將無法訪問新的 object 以分配給引用。

有趣的是,參考分配可能發生在與主 memory 不同步的芯片上緩存的 memory 中。 這意味着其他線程不會立即看到分配。 有兩種方法可以確保將引用分配推送到主 memory 其他線程可以立即看到它。 (1) 將引用聲明為 volatile 並 (2) 將引用分配放在同步塊中(退出同步塊會將緩存的引用提交到主內存)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM