單例模式詳解

2021-10-10 23:26:27 字數 1948 閱讀 3593

單例模式,屬於建立型別的一種常用的軟體設計模式。通過單例模式的方法建立的類在當前程序中只有乙個例項(根據需要,也有可能乙個執行緒中屬於單例,如:僅執行緒上下文內使用同乙個例項)

懶漢單例模式(多執行緒不安全)

餓漢單例模式(多執行緒安全)

靜態內部類單例模式(多執行緒安全)

雙檢索單例模式(dcl)(多執行緒安全)

public class singleinstance 

private static singleinstance singleinstance = null;

public static singleinstance getinstance()

return singleinstance;

}}

優點:實現了懶載入

缺點:執行緒不安全

public class singleinstance 

private static singleinstance singleinstance = new singleinstance();

public static singleinstance getinstance()

}

優點:多執行緒安全

缺點:沒有實現懶載入,可能會造成空間浪費的問題

public class singleinstance 

public static singleinstance getinstance()

private static class singleinstanceholder

}

優點:延遲載入,多執行緒安全

public class singleinstance 

private volatile static singleinstance singleinstance = null;

public static singleinstance getinstance() }}

return singleinstance;

}}

優點:延遲載入、多執行緒安全

問題解答

1、 dcl為什麼要兩次檢查singleinstance是否等於null呢?

解答:主要是為了避免多執行緒問題。首先,第一次判斷是否為null,如果不為null的話,可以直接把物件返回,不需要再獲取鎖,提高了效率。第二次再判斷是否為null的原因是:假如執行緒a持有鎖,在執行了同步**塊中的內容,但是還沒有對singleinstance進行建立;所以執行緒b已經判斷到singleinstance為null,並且已經執行到synchronized (singleinstance.class)的地方然後阻塞。等到執行緒a執行完同步**並且釋放鎖之後,執行緒b就能開始執行同步**塊裡面的內容了,如果不再加一次判斷if(singleinstance==null),執行緒b會繼續new乙個物件,這樣就導致了這個就不是單例模式了。

2、dcl中singleinstance singleinstance = null;為什麼需要加volatile關鍵字?在堆中分配物件記憶體

填充物件必要資訊+具體資料初始化+末位填充

將引用指向這個物件的堆內位址

這幾條系統指令重排序之後的順序很可能會變成1、3、2。假設執行緒a按照1、3、2順序開始執行,執行到第3步「將引用指向這個物件的堆內位址」,但是第2步「填充物件必要資訊+具體資料初始化+末位填充」卻還沒有執行,這個時候執行緒b讀取到singleinstance!=null,並開始使用singleinstance,這個時候的singleinstance雖然不為null,但是還是不可用的,所以會爆出錯誤。volatile就是為了解決這個重排序問題的,加了volatile後,1、2、3這3個步驟就會嚴格按照順序執行。

單例模式詳解

單例模式的意思就是只有乙個例項。單例模式確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。這個類稱為單例類。1.單例模式的要點 顯然單例模式的要點有三個 一是某個類只能有乙個例項 二是它必須自行建立這個例項 三是它必須自行向整個系統提供這個例項。2.單例模式的優點 1.例項控制 si...

單例模式詳解

單例模式是設計模式中比較常用的,今天我要詳細的了解一下,並且進行一些比較 public class singleton public static singleton getinstance catch interruptedexception e 單例模式的精髓就在這,類的內部可以new inst...

單例模式 詳解

保證乙個類僅有乙個例項,並且提供乙個訪問它的全域性訪問點 在該例項不存在的情況下,可以通過乙個方法建立乙個類來實現建立類的新例項 如果例項已經存在,它會簡單返回該物件的引用 建立型模式 var singleton function return var singlea singleton.getin...