標籤:
單例模式:保證一個類僅有一個執行個體,並提供一個訪問它的全域訪問點。
構成:
1.私人的建構函式
2.私人靜態執行個體
3.返回執行個體的靜態方法
public class Singleton { private static Singleton uniqueInstance = new Singleton(); private Singleton() { Console.WriteLine("this is a new singleton"); } public static Singleton getInstance() { if (uniqueInstance == null) { return uniqueInstance; } return uniqueInstance; } }
這種叫做餓漢模式,執行個體在類載入時就建立了,缺點是如果執行個體如果消耗大量的資源而沒有使用就會造成浪費,另一種懶漢模式,執行個體在被使用時才建立,
public class Singleton { private static Singleton uniqueInstance; private Singleton() { Console.WriteLine("this is a new singleton"); } public static Singleton getInstance() { if (uniqueInstance == null) { return uniqueInstance = new Singleton(); } return uniqueInstance; } }
但是這不是安全執行緒的
例如
class Program { static void Main(string[] args) { while (true) { Thread t1 = new Thread(Test); t1.Start(); } } static void Test() { Singleton s = Singleton.getInstance(); } }
執行的結果有可能是這樣
程式建立了多個執行個體,這不是我們想要的結果,原因是某個線程if (uniqueInstance == null)語句執行後讓出了使用權,當它重新獲得CPU使用權的時候,可能別的CPU已經建立了執行個體,而它並不知道,繼續執行return uniqueInstance= new Singleton();導致出現多個執行個體。
因此,要為方法加鎖
public class Singleton { private static Singleton uniqueInstance; private Singleton() { Console.WriteLine("this is a new singleton"); } private static readonly object syncRoot = new object(); public static Singleton getInstance() { lock (syncRoot) { if (uniqueInstance == null) { return uniqueInstance = new Singleton(); } } return uniqueInstance; } }
但是這又帶來了一個問題,在執行個體已經建立完成了,但還是會有大量的線程卡在lock (syncRoot),它們都還會嘗試建立執行個體,這降低了效能
為此,還要為此方法建立另外一個驗證
public static Singleton getInstance() { if (uniqueInstance == null) { lock (syncRoot) { if (uniqueInstance == null) { return uniqueInstance = new Singleton(); } } } return uniqueInstance; }
此時,當執行個體已經建立完成之後,各線程不再訪問臨界區,提高了效能
《Head First設計模式》C#實現(六)——單例模式