設計模式之單例模式
單例模式:
保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。通常我們可以讓一個全局變量是使得一個對象被訪問,但它不能防止你實例化多個對象。一個最好的辦法即時讓類自身負責保存它的唯一實例。這個類可以保證沒有其他實例可以被創建,並且它可以提供一個訪問該實例的方法。
結構圖:
經典模式:
static void Main(string[] args) { Singleton s1 = Singleton.GetInstance(); Singleton s2 = Singleton.GetInstance(); if (s1==s2)//比較兩次實例化後對象的結果是實例相同 { Console.WriteLine("兩個對象是相同的實例。"); } Console.Read(); } class Singleton { private static Singleton instance; private Singleton ()//構造方法讓其private,這就堵死了外界利用new創建此類實例的可能 { } public static Singleton GetInstance()//此方法是獲得本類實例的唯一全局訪問點 { if (instance ==null)//若實例不存在,則new一個新實例,否則返回已有的實例 { instance = new Singleton(); } return instance; } }
多線程的單例:
應用場景:多線程的程序中,多個線程同時訪問Singleton類,調用GetInstance()方法,會有可能造成創建多個實例
處理:給進程加一把鎖,lock是確保黨一個線程位於代碼段的臨界區時,另一個線程不進入臨界區,如果其他線程試圖進入鎖定的代碼,則它將一直等待,知道該對象被釋放。
代碼實現:
static void Main(string[] args) { Singleton s1 = Singleton.GetInstance(); Singleton s2 = Singleton.GetInstance(); if (s1==s2) { Console.WriteLine("兩個對象是相同的實例。"); } Console.Read(); } class Singleton { private static Singleton instance;
private static readonly object syncRoot=new object();//程序運行時創建一個靜態隻讀的進程輔助對象
private Singleton ()//構造方法讓其private,這就堵死了外界利用new創建此類實例的可能 { } public static Singleton GetInstance()//此方法是獲得本類實例的唯一全局訪問點 {
lock(syncRoot)//在同一個時刻加了鎖的那部分程序隻有一個線程可以進入
{ if (instance ==null)//若實例不存在,則new一個新實例,否則返回已有的實例 { instance = new Singleton(); } return instance; } }
靜態初始化:
這種方法不需要開發人員顯式地編寫線程安全代碼,即可解決多線程環境下它是不安全的問題。
static void Main(string[] args) { Singleton s1 = Singleton.GetInstance(); Singleton s2 = Singleton.GetInstance(); if (s1==s2) { Console.WriteLine("兩個對象是相同的實例。"); } Console.Read(); } class sealed class Singleton//阻止發生派生,而派生可能會增加實例 { private static readonly Singleton instance=new Singleton ();//在第一次引用類的任何成員時,創建實例。公共語言運行庫負責處理變量初始化 private Singleton(){} public static Singleton GetInstance() { return instance; } }關於單例的問題不止我寫的這些,還很多,多線程的單例、雙重鎖定、靜態初始化,這幾種方法在應用時需要靈活掌握,如果用合適了,效果一定非常好,所以在進行單例模式的應用時要多想,多用。
最後更新:2017-04-03 12:55:08