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類型的變量。