保證一個類僅有一個執行個體,並提供一個該執行個體的全域訪問點。
——《設計模式》
單例模式的概念很簡單,下面以C#語言為例子,列出常見單例寫法的優缺點。
1、簡單實現
public sealed class Singleton { static Singleton instance = null; public void Show() { Console.WriteLine( "instance function"); } private Singleton() { } public static Singleton Instance { get { if (instance == null) { instance = new Singleton(); } return instance; } } }
評註:
對於線程來說不安全
單線程中已滿足要求
優點:
由於執行個體是在 Instance 屬性方法內部建立的,因此類可以使用附加功能
直到對象要求產生一個執行個體才執行執行個體化;這種方法稱為“惰性執行個體化”。惰性執行個體化避免了在應用程式啟動時執行個體化不必要的 singleton。
2、線程的安全
public sealed class Singleton { static Singleton instance = null; private static readonly object padlock = new object(); private Singleton() { } public static Singleton Instance { get { lock (padlock) { if (instance == null) { instance = new Singleton(); } } return instance; } } }
評註:
同一個時刻加了鎖的那部分程式只有一個線程可以進入
對象執行個體由最先進入的那個線程建立
後來的線程在進入時(instence == null)為假,不會再去建立對象執行個體
增加了額外的開銷,損失了效能
3、雙重鎖定
public sealed class Singleton { static Singleton instance = null; private static readonly object padlock = new object(); private Singleton() { } public static Singleton Instance { get { if (instance == null) { lock (padlock) { if (instance == null) { instance = new Singleton(); } } } return instance; } } }
評註:
多安全執行緒
線程不是每次都加鎖
允許執行個體化延遲到第一次訪問對象時發生
4、靜態初始化
public sealed class Singleton { private static readonly Singleton instance = null; static Singleton() { instance = new Singleton(); } private Singleton() { } public static Singleton Instance { get { return instance; } } }
評註:
依賴公用語言運行庫負責處理變數初始化
公用靜態屬性為訪問執行個體提供了一個全域訪問點
對執行個體化機制的控制權較少(.NET代為實現)
靜態初始化是在 .NET 中實現 Singleton 的首選方法
小註:
靜態建構函式既沒有存取修飾詞,C#會自動把他們標記為private,之所以必須標記為private,
是為了阻止開發人員寫的代碼調用它,對它的調用總是由CLR負責的。
5、延遲初始化
public sealed class Singleton { private Singleton() { } public static Singleton Instance { get { return Nested.instance; } } public static void Hello() { } private class Nested { internal static readonly Singleton instance = null; static Nested() { instance = new Singleton(); } } }
評註:
初始化工作由Nested類的一個靜態成員來完成,這樣就實現了延遲初始化。
由於靜態函數的調用時機,是在類被執行個體化或者靜態成員被調用的時候進行調用,並且是由.net架構來調用靜態建構函式來初始化靜態成員變數,所以,如果按照寫法四來寫,再調用Hello方法的時候,就會執行個體化出來Singleton執行個體,這不是我們想看到的,因為我們有可能只是想用Hello方法,而不是別的。
注意事項:
1、Singleton模式中的執行個體構造器可以設定為protected以允許子類派生。
2、Singleton模式一般不要支援ICloneable介面,因為這可能會導致多個對象執行個體,與Singleton模式的初衷違背。
3、Singleton模式一般不要支援序列化,因為這也有可能導致多個對象執行個體,同樣與Singleton模式的初衷違背。
4、Singletom模式只考慮到了對象建立的管理,沒有考慮對象銷毀的管理。就支援記憶體回收的平台和對象的開銷來講,我們一般沒有必要對其銷毀進行特殊的管理。
總結:
1、Singleton模式是限制而不是改進類的建立。
2、理解和擴充Singleton模式的核心是“如何控制使用者使用new對一個類的構造器的任意調用”。
3、可以很簡單的修改一個Singleton,使它有少數幾個執行個體,這樣做是允許的而且是有意義的。
以上就是單例模式及常見寫法分析(設計模式01)的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!