標籤:同步 return stat 調用 互斥 turn 靜態方法 others 多個
在程式的設計過程中很多時候系統會要求對於某個類型在一個應用程式定義域中只出現一次,或者是因為效能的考慮,或者是由於邏輯的要求,總之是有這樣的需求的存在,那在設計模式中正好有這麼一種模式可以來滿足這樣的要求。
在C#中實現單例模式可以通過定義私人的建構函式來實現,當然,還可以通過定義靜態建構函式來實現。在Singleton模式中可以利用類的靜態構造器來執行完成單例模式的原因是當靜態變數被訪問的時候,CLR會調用類的靜態構造器(類型構造器),建立靜態類的類型對象,CLR希望確保每個應用程式定義域內只執行一次類型構造器,為了做到這一點,在調用類型構造器時,CLR會為靜態類加一個互斥的線程同步鎖,因此,如果多個線程試圖同時調用某個類型的靜態構造器時,那麼只有一個線程可以獲得對靜態類的訪問權,其他的線程都被阻塞。第一個線程執行完 類型構造器的代碼並釋放構造器之後,其他阻塞的線程被喚醒,然後發現構造器被執行過,因此,這些線程不再執行構造器,只是從構造器簡單的返回。如果再一次調用這些方法,CLR就會意識到類型構造器被執行過,從而不會在被調用。調用類中的靜態方法,或者訪問類中的靜態成員變數,過程同上,所以說靜態成員是安全執行緒的。
看過上面的描述,可以瞭解到,靜態成員在C#Runtime中進行了特殊的處理,特別適合建立單例模式。
public class Singleton { public static readonly Singleton _instance; static Singleton() { _instance=new Singleton(); } private Singleton() { } }
上面簡短的幾行代碼就建立了一個標準的單利模式,其中,定義私人建構函式是為了防止使用new關鍵字在類的外部存取建構函式,使用靜態建構函式,是為了初始化這個公用的,共全域訪問的唯讀欄位_instance。從上面的解釋來看,這種方式還可以免費的使用CLR送的互斥鎖來同步執行並且CLR保證靜態建構函式只被執行一次,也就是說,完美的實現了單例模式的所有要求。因此,這種方法無論從效率還是簡潔上面都是最好的選擇,還有一種雙重判斷的方式來實現單例模式:
public class AnotherSingleton { private AnotherSingleton() { } private static AnotherSingleton _instance; private static readonly object PadLock=new object(); public static AnotherSingleton GetInstance() { if (_instance==null) { lock (PadLock) { if (_instance==null) { _instance=new AnotherSingleton(); } } } return _instance; } }
利用上面這段代碼也可以建立一個單例模式,但是由於使用鎖,所以初始化方面時間要稍長一些,不過這段代碼實現的單例模式也是適用於在多線程環境下啟動並執行。以上兩個例子就是最常用最好用的單例模式的實現方式。
由於單例模式不用考慮具體的使用環境,只要需求,就可以實現,所以這篇文章就沒涉及到相應的情境。先到這裡吧。
C#設計模式之建立類模式:單例模式