建立型模式---單件模式(Singleton Pattern)
動機(Motivation):
在軟體系統中,經常有這樣一些特殊的類,必須保證它們在系統中只存在一個執行個體,才能確保它們的邏輯正確性、以及良好的效率。
如何繞過常規的構造器,提供一種機制來保證一個類只建立一個執行個體?
這應該是類設計者的責任,而不是類使用者的責任。
結構圖:
意圖:
保證一個類僅有一個執行個體,並提供一個訪問它的全域訪問點。
------<<設計模式>>GOF
生活的例子:
適用性:
(1)當類只能有一個執行個體而且客戶可以從一個眾所周知的訪問點訪問它時。
(2)當這個唯一執行個體應該是通過子類化可擴充的,並且客戶應該無需更改代碼就能使用一個擴充的執行個體時。
代碼實現:
(1)單線程Singleton實現
class SingleThread_Singleton
{
private static SingleThread_Singleton instance = null;
private SingleThread_Singleton(){}
public static SingleThread_Singleton Instance
{
get
{
if (instance == null)
{
instance = new SingleThread_Singleton();
}
return instance;
}
}
}
以上代碼在單線程情況下不會出現任何問題。但是在多線程的情況下卻不是安全的。
如兩個線程同時運行到 if (instance == null)判斷是否被執行個體化,一個線程判斷為True後,在進行建立
instance = new SingleThread_Singleton()之前,另一個線程也判斷(instance == null),結果也為True.
這樣就就違背了Singleton模式的原則(保證一個類僅有一個執行個體)。
怎樣在多線程情況下實現Singleton?
(2)多線程Singleton實現: 1 class MultiThread_Singleton
2 {
3 private static volatile MultiThread_Singleton instance = null;
4 private static object lockHelper = new object();
5 private MultiThread_Singleton() { }
6 public static MultiThread_Singleton Instance
7 {
8 get
9 {
10 if (instance == null)
11 {
12 lock (lockHelper)
13 {
14 if (instance == null)
15 {
16 instance = new MultiThread_Singleton();
17 }
18 }
19 }
20 return instance;
21 }
22 }
23
此程式對多線程是安全的,使用了一個輔助對象lockHelper,保證只有一個線程建立執行個體(如果instance為空白,保證只有一個線程instance = new MultiThread_Singleton();建立唯一的一個執行個體)。(Double Check)
請注意一個關鍵字volatile,如果去掉這個關鍵字,還是有可能發生線程不是安全的。
volatile 保證嚴格意義的多線程編譯器在代碼編譯時間對指令不進行微調。
(3)靜態Singleton實現
3 class Static_Singleton
4 {
5 public static readonly Static_Singleton instance = new Static_Singleton();
6 private Static_Singleton() { }
7 }
以上代碼展開等同於1 class Static_Singleton
2 {
3 public static readonly Static_Singleton instance;
4 static Static_Singleton()
5 {
6 instance = new Static_Singleton();
7 }
8 private Static_Singleton() { }
9 }由此可以看出,完全符合Singleton的原則。
優點: 簡潔,易懂
缺點: 不可以實現帶參數執行個體的建立。(註:以上代碼及資訊借鑒於李建忠老師的MSDN和TerryLee的文章。) 轉自:http://www.cnblogs.com/abcdwxc/archive/2007/08/28/873342.html