一、定義
單例就是一個例項。從始至終我們只需要維護這麼一個例項,來節約資源。
二、例項
我們用建構函式建立例項,現在我們要維護此類只維護一個例項,那麼我們需要將生產例項的能力也就是建構函式加以限制。
並通過一個統一的函式對外公開我們維護的唯一的例項。
2.1 第一代單例模式:利用懶載入,在確實要使用例項的時候才會建立單例
public class Single_1 { private static Single_1 single = null; private Single_1() { } public static Single_1 GetInstance() { if (single == null) { single = new Single_1(); Console.WriteLine("建立例項"); } return single; } }
保證建立一個例項,但是隻是在單執行緒的環境下,如果多執行緒會怎麼樣?試試!!
客戶端併發100執行緒:
//------------------------單例模式----------------------- System.Threading.Tasks.Parallel.For(0, 100, t => { Singleton.Single_1.GetInstance(); }); Console.ReadKey();
執行結果:執行結果由系統隨即切片,可能結果不同。但是確實存在建立了多個例項。
2.2 針對多執行緒之間的同步問題:加鎖
public class Single_2 { private static Single_2 single = null; private static object lockkey = new object(); private Single_2() { } public static Single_2 GetInstance() { lock (lockkey) { if (single == null) { single = new Single_2(); Console.WriteLine("建立例項"); } return single; } } }
效率高點的雙檢鎖:
public static Single_2 GetInstance() { if (single == null) { lock (lockkey) { if (single == null) { single = new Single_2(); Console.WriteLine("建立例項"); } } } return single; }
2.3 靜態建構函式構造單例:我們知道靜態建構函式是執行緒安全的
public class Single_3 { private static Single_3 single = null; private Single_3() { } static Single_3() { single = new Single_3(); Console.WriteLine("靜態例項"); } public static Single_3 GetInstance() { return single; } }
三、總結
合理使用單例模式可以提高效能節約記憶體。當然,現實專案中有很多的例子,至少專案中可以很常見單例子模式。