一、懶漢模式:即第一次調(diào)用該類實(shí)例的時(shí)候才產(chǎn)生一個(gè)新的該類實(shí)例,,并在以后僅返回此實(shí)例,。 需要用鎖,來(lái)保證其線程安全性:原因:多個(gè)線程可能進(jìn)入判斷是否已經(jīng)存在實(shí)例的if語(yǔ)句,,從而non thread safety. 使用double-check來(lái)保證thread safety.但是如果處理大量數(shù)據(jù)時(shí),,該鎖才成為嚴(yán)重的性能瓶頸。 1,、靜態(tài)成員實(shí)例的懶漢模式: [cpp] view plaincopy
2、內(nèi)部靜態(tài)實(shí)例的懶漢模式 這里需要注意的是,,C++0X以后,,要求編譯器保證內(nèi)部靜態(tài)變量的線程安全性,可以不加鎖,。但C++ 0X以前,,仍需要加鎖。 [cpp] view plaincopy
二,、餓漢模式:即無(wú)論是否調(diào)用該類的實(shí)例,,在程序開始時(shí)就會(huì)產(chǎn)生一個(gè)該類的實(shí)例,并在以后僅返回此實(shí)例,。 由靜態(tài)初始化實(shí)例保證其線程安全性,,WHY?因?yàn)殪o態(tài)實(shí)例初始化在程序開始時(shí)進(jìn)入主函數(shù)之前就由主線程以單線程方式完成了初始化,,不必?fù)?dān)心多線程問(wèn)題,。 故在性能需求較高時(shí),應(yīng)使用這種模式,,避免頻繁的鎖爭(zhēng)奪,。 [cpp] view plaincopy
m_pInstance指向的空間什么時(shí)候釋放呢?更嚴(yán)重的問(wèn)題是,,該實(shí)例的析構(gòu)函數(shù)什么時(shí)候執(zhí)行,? 如果在類的析構(gòu)行為中有必須的操作,比如關(guān)閉文件,,釋放外部資源,,那么上面的代碼無(wú)法實(shí)現(xiàn)這個(gè)要求。我們需要一種方法,,正常的刪除該實(shí)例,。 可以在程序結(jié)束時(shí)調(diào)用GetInstance(),,并對(duì)返回的指針掉用delete操作,。這樣做可以實(shí)現(xiàn)功能,,但不僅很丑陋,而且容易出錯(cuò),。因?yàn)檫@樣的附加代碼很容易被忘記,,而且也很難保證在delete之后,沒(méi)有代碼再調(diào)用GetInstance函數(shù),。 一個(gè)妥善的方法是讓這個(gè)類自己知道在合適的時(shí)候把自己刪除,,或者說(shuō)把刪除自己的操作掛在操作系統(tǒng)中的某個(gè)合適的點(diǎn)上,使其在恰當(dāng)?shù)臅r(shí)候被自動(dòng)執(zhí)行,。 我們知道,,程序在結(jié)束的時(shí)候,系統(tǒng)會(huì)自動(dòng)析構(gòu)所有的全局變量,。事實(shí)上,,系統(tǒng)也會(huì)析構(gòu)所有的類的靜態(tài)成員變量,就像這些靜態(tài)成員也是全局變量一樣,。利用這個(gè)特征,,我們可以在單例類中定義一個(gè)這樣的靜態(tài)成員變量,而它的唯一工作就是在析構(gòu)函數(shù)中刪除單例類的實(shí)例,。如下面的代碼中的CGarbo類(Garbo意為垃圾工人):
[cpp] view plaincopy
類CGarbo被定義為CSingleton的私有內(nèi)嵌類,,以防該類被在其他地方濫用。 程序運(yùn)行結(jié)束時(shí),,系統(tǒng)會(huì)調(diào)用CSingleton的靜態(tài)成員Garbo的析構(gòu)函數(shù),,該析構(gòu)函數(shù)會(huì)刪除單例的唯一實(shí)例。 使用這種方法釋放單例對(duì)象有以下特征: 在單例類內(nèi)部定義專有的嵌套類,; 在單例類內(nèi)定義私有的專門用于釋放的靜態(tài)成員,; 利用程序在結(jié)束時(shí)析構(gòu)全局變量的特性,選擇最終的釋放時(shí)機(jī),; 使用單例的代碼不需要任何操作,,不必關(guān)心對(duì)象的釋放。
具體代碼如下:
[cpp] view
plaincopy
輸出結(jié)果如下:
Singleton ctor p1 == p2 Garbo dtor Singleton dtor |
|
來(lái)自: 520jefferson > 《c/c 》