单列模式
最近在學(xué)設(shè)計(jì)模式,學(xué)到創(chuàng)建型模式的時(shí)候,碰到單例模式(或叫單件模式),現(xiàn)在整理一下筆記。
在《Design Patterns:Elements of Resuable Object-Oriented Software》中的定義是:Ensure?a class only has one instance,and provide a global point of access to。它的主要特點(diǎn)不是根據(jù)客戶程序調(diào)用生成一個(gè)新的實(shí)例,而是控制某個(gè)類型的實(shí)例數(shù)量-唯一一個(gè)。(《設(shè)計(jì)模式-基于C#的工程化實(shí)現(xiàn)及擴(kuò)展》,王翔)。也就是說(shuō),單例模式就是保證在整個(gè)應(yīng)用程序的生命周期中,在任何時(shí)刻,被指定的類只有一個(gè)實(shí)例,并為客戶程序提供一個(gè)獲取該實(shí)例的全局訪問(wèn)點(diǎn)。
一、經(jīng)典模式:
publicclass Singleton{
privatestatic Singleton instance;
private Singleton()
{
}
publicstatic Singleton GetInstance()
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}
解析如下:
1)首先,該Singleton的構(gòu)造函數(shù)必須是私有的,以保證客戶程序不會(huì)通過(guò)new()操作產(chǎn)生一個(gè)實(shí)例,達(dá)到實(shí)現(xiàn)單例的目的;
2)因?yàn)殪o態(tài)變量的生命周期跟整個(gè)應(yīng)用程序的生命周期是一樣的,所以可以定義一個(gè)私有的靜態(tài)全局變量instance來(lái)保存該類的唯一實(shí)例;
3)必須提供一個(gè)全局函數(shù)訪問(wèn)獲得該實(shí)例,并且在該函數(shù)提供控制實(shí)例數(shù)量的功能,即通過(guò)if語(yǔ)句判斷instance是否已被實(shí)例化,如果沒(méi)有則可以同new()創(chuàng)建一個(gè)實(shí)例;否則,直接向客戶返回一個(gè)實(shí)例。
在這種經(jīng)典模式下,沒(méi)有考慮線程并發(fā)獲取實(shí)例問(wèn)題,即可能出現(xiàn)兩個(gè)線程同時(shí)獲取instance實(shí)例,且此時(shí)其為null時(shí),就會(huì)出現(xiàn)兩個(gè)線程分別創(chuàng)建了instance,違反了單例規(guī)則。因此,需對(duì)上面代碼修改。
二、多線程下的單例模式
1、Lazy模式
publicclass Singleton{
privatestatic Singleton instance;
privatestaticobject _lock=newobject();
private Singleton()
{
}
publicstatic Singleton GetInstance()
{
if(instance==null)
{
lock(_lock)
{
if(instance==null)
{
instance=new Singleton();
}
}
}
return instance;
}
}
上述代碼使用了雙重鎖方式較好地解決了多線程下的單例模式實(shí)現(xiàn)。先看內(nèi)層的if語(yǔ)句塊,使用這個(gè)語(yǔ)句塊時(shí),先進(jìn)行加鎖操作,保證只有一個(gè)線程可以訪問(wèn)該語(yǔ)句塊,進(jìn)而保證只創(chuàng)建了一個(gè)實(shí)例。再看外層的if語(yǔ)句塊,這使得每個(gè)線程欲獲取實(shí)例時(shí)不必每次都得加鎖,因?yàn)橹挥袑?shí)例為空時(shí)(即需要?jiǎng)?chuàng)建一個(gè)實(shí)例),才需加鎖創(chuàng)建,若果已存在一個(gè)實(shí)例,就直接返回該實(shí)例,節(jié)省了性能開(kāi)銷。
2、餓漢模式
這種模式的特點(diǎn)是自己主動(dòng)實(shí)例。
publicsealedclass Singleton{
privatestaticreadonly Singleton instance=new Singleton();
private Singleton()
{
}
publicstatic Singleton GetInstance()
{
returninstance;
}
}
上面使用的readonly關(guān)鍵可以跟static一起使用,用于指定該常量是類別級(jí)的,它的初始化交由靜態(tài)構(gòu)造函數(shù)實(shí)現(xiàn),并可以在運(yùn)行時(shí)編譯。在這種模式下,無(wú)需自己解決線程安全性問(wèn)題,CLR會(huì)給我們解決。由此可以看到這個(gè)類被加載時(shí),會(huì)自動(dòng)實(shí)例化這個(gè)類,而不用在第一次調(diào)用GetInstance()后才實(shí)例化出唯一的單例對(duì)象。
?
轉(zhuǎn)載于:https://www.cnblogs.com/cpetcoandy/archive/2011/11/10/2244407.html
總結(jié)
- 上一篇: SQL JOIN连接分类[转]
- 下一篇: zTree v2.6 - v3.0 文件