- 單例模式:
保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn)预烙。
為了解決兩個(gè)問(wèn)題:
//簡(jiǎn)單單例
class Singleton
{
private static Singleton instance;
private Singleton()
{
}
public static Singleton GetInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
//客戶端代碼
static void Main(string[] args)
{
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if(s1 == s2){
Console.WriteLine("兩個(gè)對(duì)象是相同的實(shí)例");
}
Console.Read();
}
- 多線程單例
當(dāng)多個(gè)線程同時(shí)訪問(wèn) Singleton 類的時(shí)候酬屉,會(huì)有可能創(chuàng)建出多個(gè)實(shí)例负懦。這時(shí)就需要一把 lock 來(lái)確保當(dāng)一個(gè)線程位于代碼的臨界區(qū)時(shí),另一個(gè)線程不進(jìn)入臨界區(qū)。如果其他線程試圖進(jìn)入鎖定的代碼规肴,那么它將一直等待,直到該對(duì)象被釋放祭示。
//多線程單例
class Singleton
{
private static Singleton instance;
private static readonly object syncRoot = new object();
private Singleton()
{
}
//這樣做的缺點(diǎn)就是 每次創(chuàng)建的時(shí)候都需要 lock。
// public static Singleton GetInstance()
// {
// lock(syncRoot)
// {
// if(instance == null)
// {
// instance = new Singleton();
// }
// }
// return instance;
// }
//先判斷實(shí)例是否存在,不存在再加鎖處理
public static Singleton GetInstance()
{
//判斷兩次實(shí)例是否為null 的道理在于,第一次判斷是為了避免頻繁加鎖
/*第二次判斷是為了防止多線程多次創(chuàng)建實(shí)例當(dāng)多個(gè)線程同時(shí)訪問(wèn)的時(shí)候侧巨,會(huì)允許一個(gè)線程進(jìn)去,當(dāng)一個(gè)線程創(chuàng)建完對(duì)象之后贼陶,另一個(gè)線程進(jìn)入如果不判斷非空的情況,那么也會(huì)出現(xiàn)重復(fù)創(chuàng)建的情況巧娱。*/
if(instance == null){
lock(syncRoot){
if(instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
//這種靜態(tài)初始化方式是在自己被加載的時(shí)候就將自己實(shí)例化碉怔,上面的在第一次被引用的時(shí)候才會(huì)將自己實(shí)例化,屬于懶加載禁添。
public sealed class Singleton
{
//在第一次引用類的任何成員時(shí)創(chuàng)建實(shí)例撮胧。公共語(yǔ)言運(yùn)行庫(kù)負(fù)責(zé)處理變量初始化
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton GetInstance()
{
return instance;
}
}
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者