Singleton…
那天看到點部落的高手分享Singleton
忽然想要自己也記錄一下心得
其實我對這個pattern算是特別有印象
為什麼會特別印象深刻呢?
第一:當初小弟在寫actionscript做flash動畫時因為flash的動畫中有時會需要設定某些物件只能在同一場景出現一個
(這些情況使用singleton就很方便,把只能產生一個的責任讓物件本身自己來背算是很適當的處理方式。)
第二:有一次小弟問同事,你覺得哪種pattern最簡單,同事跟我說singleton最簡單,小弟笑了…
關於Singleton這個pattern
其實說簡單也沒那麼簡單
講起來好像很繞舌
其實我想說的是這個pattern要寫很簡單,但是也是有些小地方要注意
小弟分享一下讀書心得~
首先一般來說singleton最基本的兩種寫法
class Singleton
{
private static Singleton _singleton;
private Singleton() { }
public static Singleton GetInstance()
{
if (_singleton == null)
{
_singleton = new Singleton();
}
return _singleton;
}
}
class Singleton
{
private readonly static Singleton _singleton = new Singleton();
private Singleton() { }
public static Singleton Instance
{
get
{
return _singleton;
}
}
}
第一種寫法乍看之下比較不占資源,畢竟成是沒呼叫到Singleton.GetInstance()就永遠不會產生一個singleton物件
但是每一次的呼叫GetInstance就要不斷的判斷if (_singleton == null)也是一個開銷
第二種則是在程式開始執行就產生了一個singleton物件
小弟是覺得如果不一定會instance的話,那也就不需要特地使用它了(將他加到專案中)
當然實務上還是需要在判斷要用哪種做法
另外當使用第一種做法實需要多判斷多執行緒的問題
首先我將第一種做法改成以下
class Singleton
{
private static Singleton _singleton;
public static int count = 0;
private Singleton() { }
public static Singleton GetInstance()
{
Thread.Sleep(1000);
if (_singleton == null)
{
count++;
_singleton = new Singleton();
}
return _singleton;
}
public string GetCount()
{
return count.ToString();
}
}
每次GetInstance都要等一秒,這樣我比叫好模擬
然後我呼叫的程式如下
Singleton singleton, singleton1;
Action act = new Action(delegate()
{
singleton = Singleton.GetInstance();
});
Action act1 = new Action(delegate()
{
singleton1 = Singleton.GetInstance();
});
IAsyncResult actResult = act.BeginInvoke(null, null);
IAsyncResult act1Result = act1.BeginInvoke(null, null);
WaitHandle[] waithandlearray = new WaitHandle[] { actResult.AsyncWaitHandle, act1Result.AsyncWaitHandle };
while (!WaitHandle.WaitAll(waithandlearray, 3000, false))
{
}
Console.WriteLine(Singleton.count.ToString());
結果跑到18行時程式給我的count是2。
這就證明了第一種寫法在多執行緒是有可能會出錯的
所以要改成
class Singleton
{
private static Singleton _singleton;
private static Object thisLock = new Object();
private Singleton() { }
public static Singleton GetInstance()
{
if (_singleton == null)
{
lock (thisLock)
{
_singleton = new Singleton();
}
}
return _singleton;
}
}
這樣在多執行緒的呼叫中才能確保只會產生一個Singleton物件
如果Singleton不能防止產生超過一個物件的話,那麼這模式也就完全沒任何意義了不是?
這是需要注意的。
有問題請各位大大多多指教,謝謝