Telegram開源項目之單例模式

NotificationCenter的單例模式

public class NotificationCenter {
    private static volatile NotificationCenter Instance = null;

    public static NotificationCenter getInstance() {
        NotificationCenter localInstance = Instance;
        if (localInstance == null) {
            synchronized (NotificationCenter.class) {
            //多線程環境下,之前得到的instance爲null,但現在很有可能在鎖定NotificationCenter.class之前已經被實例化了,所以需要進一步判斷instance是否實例化。
                localInstance = Instance;
                if (localInstance == null) {
                    Instance = localInstance = new NotificationCenter();
                }
            }
        }
        return localInstance;
    }
}

NotificationCenter的單例模式分析

這種單例模式是採用雙重校驗鎖的線程安全的單例模式。是效率最好的安全性最好的一種寫法

Instance加上了volatile關鍵字確保了多線程環境下防止重排序,避免在多線程環境下實例化NotificationCenter對象時得到的引用時未初始化的。

實例化一個對象其實可以分爲三個步驟:
  (1)分配內存空間。
  (2)初始化對象。
  (3)將內存空間的地址賦值給對應的引用。
但是由於操作系統可以對指令進行重排序,所以上面的過程也可能會變成如下過程:
  (1)分配內存空間。
  (2)將內存空間的地址賦值給對應的引用。
  (3)初始化對象
  如果是這個流程,多線程環境下就可能將一個未初始化的對象引用暴露出來,從而導致不可預料的結果。因此,爲了防止這個過程的重排序,我們需要將變量設置爲volatile類型的變量。

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