單例模式雙重檢驗鎖的判斷是否爲null的意義

關於雙重檢驗鎖,首先簡單來看一個小例子,代碼如下:

public class Singleton{
    private static Singleton instance = null;
    private Singleton(){}

    public static Singleton getInstance(){
        if (instance == null) {//e1
            synchronized(Singleton.class){
                if (instance == null) {//e2
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

雙重檢驗鎖是對同步塊加鎖的方法。爲什麼會稱爲雙重檢驗,因爲有兩次對 instance == null的檢查,一次中同步塊中一次中同步塊外部。

對於兩次instance的是否爲空的判斷解釋:
1.爲何在synchronization外面的判斷?

爲了提高性能!如果拿掉這次的判斷那麼在行的時候就會直接的運行synchronization,所以這會使每個getInstance()都會得到一個靜態內部鎖,這樣的話鎖的獲得以及釋放的開銷(包括上下文切換,內存同步等)都不可避免,降低了效率。所以在synchronization前面再加一次判斷是否爲空,則會大大降低synchronization塊的執行次數。

2.爲何在synchronization內部還要執行一次呢?

因爲可能會有多個線程一起進入同步塊外的 if,如果在同步塊內不進行二次檢驗的話就會生成多個實例了。

PS:雙重檢驗情況下,保存實例的唯一的靜態變量要用volatile修飾,volatile能禁止指令重排。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章