325
技術社區[雲棲]
DCL雙重加鎖檢查多線程不安全問題
Singleton instance = new Singleton()
這句,這裏看起來是一句話,但實際上它並不是一個原子操作,我們隻要看看這句話被編譯後在JVM執行的對應匯編代碼就發現,這句話被編譯成8條匯編指令,大致做了3件事情:
1.給Singleton的實例分配內存。
2.初始化Singleton()的構造器
3.將instance對象指向分配的內存空間(注意到這步instance就非null了)。
但是,由於Java編譯器允許處理器亂序執行,以及JDK1.5之前JMM(Java Memory Medel,即Java內存模型)中Cache、寄存器到主內存回寫順序的規定,上麵的第二點和第三點的順序是無法保證的,也就是說,執行順序可能是1-2-3也可能是1-3-2,如果是後者,並且在3執行完畢、2未執行之前,被切換到線程B上,這時候instance因為已經在線程A內執行過了第三點,instance已經是非空了,所以線程B直接拿走instance,然後使用,然後順理成章地報錯,而且這種難以跟蹤難以重現的錯誤很可能會隱藏很久。
最後更新:2017-06-14 18:02:08