2013-08-02 64 views
2

這是從Java double checked locking後續。Java雙重檢查鎖定解決方案?

以下代碼片段有2個有趣的特徵。

1)它需要在對象準備好使用之前調用一個單獨的init()方法。所以volatile不起作用(我知道,爲什麼我不把代碼放入init()到構造函數中呢?這裏就是爲了說明目的)。

2)它使用一個tmp變量來完成初始化並在初始化完成後分配給實例。

if (instance == null) { 
synchronized (mutex) { 
    if (instance == null) { 
     AClass tmpInstance = new AClass(); 
     tmpInstance.init(); 
     instance = tmpInstance; 
    } 
} 
} 

那麼,這個問題到重排序問題,即,可以例如被前tmpInstance.init()分配給tmpInstance被稱爲?

謝謝, 富

回答

1

所以,被這個問題到重排序問題,即,可能實例中 分配給tmpInstance之前tmpInstance.init()被調用?

不,但它受易失性解決方案的可見性問題影響。所以你仍然應該聲明instance不穩定。

現在它不受重新排序的原因。監視器輸入後,正常商店不能重新排序。

http://g.oswego.edu/dl/jmm/cookbook.html

第一次操作:MonitorEnter

第二操作:NormalStore

可以重新排序:沒有

2

所有的事情是,你作爲最後分配給instance操作,畢竟初始化完成。由於instance(有希望)是不穩定的,這將確保所有的初始化對後面的讀者都可見。

順便說一句,你真的沒有必要學習所有允許重新排序的規則:這只是JIT編譯器實現者的強制性閱讀。

作爲一名Java程序員,您需要牢記Java存儲器模型爲您提供的兩個簡單保證(一個是關於​​,另一個關於volatile)。 JMM重寫(從JLS 3開始)的重點就是允許我們針對一個非常簡單的併發模型進行編程。