懶漢式單例:在第一次被引用時才會将自己執行個體化。
class Singleton
{
private static Singleton instance;
//程式運作時建立一個靜态隻讀的程序輔助對象
private static readonly object syncRoot = new object();
//構造方法讓其private,外界就無法使用new建立執行個體
private Singleton()
{
}
//獲得本類執行個體的唯一全局通路點
public static Singleton GetInstance()
/*
* 先判斷執行個體是否存在,不存在再加鎖處理。這樣不用讓線程每次都加鎖,而隻是在執行個體未被建立的時候再加鎖處理。同時也能保證多線程安全。
* 這種做法被稱Double-Check Locking(雙重鎖定)。
* 兩次判斷instance==null是因為當同時有兩個線程調用GetInstance()方法時,它們将可以通過第一重instance==null的判斷,然後由于lock機制,
* 這兩個線程則隻有一個進入,另一個在外排隊等候,必須要其中的一個進入并出來後,另一個才能進入。而此時如果沒有了第二重的instance是否為
* null的判斷,則第一個線程建立了執行個體,而第二個線程還是可以繼續再建立新的執行個體,這就沒有達到單例的目的。
*/
if (instance == null)
{
//在同一個時刻,隻有一個線程可以進入
lock (syncRoot)
{
//若執行個體不存在,則new一個新的執行個體,否則傳回已有的執行個體
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
餓漢式代例:自己被加載時就将自己執行個體化。
/// <summary>
/// 靜态初始化方法
/// C#與公共語言運作庫也提供了一種‘靜态初始化’方法,這種方法不需要開發人員顯式地編寫線程安全代碼,即可解決多線程環境下它是不安全的問題。
/// </summary>
sealed class Singletom2
//sealed 陰止發派生,而派生可能會增加執行個體
//在第一次引用類的任何成員時建立執行個體。公共語言運作庫負責處理變量初始化
private static readonly Singletom2 instance = new Singletom2();
private Singletom2() { }
public static Singletom2 GetInstance()
靜态初始化方式提前占用系統資源,懶漢方式面臨多線程通路安全性問題。從C#語言角度來講,餓漢式的單例類已經足夠滿足我們的需求了。