版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
前言什么是單例模式?單例模式,屬于創(chuàng)建類型的一種常用的軟件設(shè)計(jì)模式。通過單例模式的方法創(chuàng)建的類在當(dāng)前進(jìn)程中只有一個(gè)實(shí)例(根據(jù)需要,也有可能一個(gè)線程中屬于單例,如:僅線程上下文內(nèi)使用同一個(gè)實(shí)例)上面是百度百科給出的解釋。大家都知道,面向?qū)ο蟮乃枷刖褪俏覀兛梢园岩粋€(gè)類實(shí)例很多次,每次實(shí)例出來(lái)的都是一個(gè)對(duì)象,意味著你可以創(chuàng)建很多個(gè)基于這個(gè)類的對(duì)象。單例模式,說(shuō)白了,就是這些對(duì)象本質(zhì)都是同一個(gè),整個(gè)程序中,不管在哪里用,使用的都是同一個(gè)實(shí)例對(duì)象。如果我們創(chuàng)建了一個(gè)China類,我們可以一直new嗎?不可以,因?yàn)槭澜缟现挥幸粋€(gè)China,所以我們使用的都是同一個(gè)China對(duì)象。Version1-非線程安全
publicclassChina
{
private
China()
{
}
privatestaticChinachina
=
null;
publicstaticChinaInstance
{
get
{
if
(china
==
null)
{
Console.WriteLine("實(shí)例化對(duì)象");
china
=
newChina();
}
return
china;
}
}
}最簡(jiǎn)單的實(shí)現(xiàn)方式如上圖,創(chuàng)建一個(gè)私有的靜態(tài)對(duì)象和私有構(gòu)造方法,然后在CreateInstance方法里,加一個(gè)判斷,如果為Null,就重新實(shí)例化一下,否則直接返回。這種寫法從邏輯上是沒問題的,但是是否會(huì)出現(xiàn)這個(gè)if(china==null)判斷,同時(shí)執(zhí)行,這樣就麻煩了。所以這種寫法在單線程的程序是沒問題的,但是在多線程中,是可能會(huì)有問題的。我們做個(gè)測(cè)試,測(cè)試代碼如下:
classProgram
{
staticvoidMain(string[]
args)
{
for
(inti
=
0;
i
<
10;
i++)
{
newTaskFactory().StartNew(()
=>
{
Chinachina
=
China.Instance;
});
Thread.Sleep(10);
}
Console.ReadLine();
}
}上面的代碼,就是創(chuàng)建10個(gè)線程,都執(zhí)行CreatInstance方法,那么最終是輸出多少次Console.WriteLine("實(shí)例化對(duì)象")呢?我們測(cè)試發(fā)現(xiàn),這個(gè)輸出結(jié)果是不唯一的,有時(shí)候會(huì)輸出5次,有時(shí)候會(huì)輸出2次,但是一般都是超過1次,這個(gè)就說(shuō)明對(duì)象被多次實(shí)例化了,這就違背了單例模式的原則。Version2-簡(jiǎn)單的線程安全既然出現(xiàn)問題,那么我們就需要做一下優(yōu)化,優(yōu)化之后的代碼如下:
publicclassChina
{
private
China()
{
}
privatestaticChinachina
=
null;
privatestaticobjectobjlock
=
newobject();
publicstaticChinaInstance
{
get
{
lock
(objlock)
{
Console.WriteLine("執(zhí)行判斷");
if
(china
==
null)
{
Console.WriteLine("實(shí)例化對(duì)象");
china
=
newChina();
}
}
return
china;
}
}
}對(duì)比看下,就是加了一個(gè)同步鎖,這樣就可以避免同時(shí)執(zhí)行的情況,并且,我們?cè)趌ock里加了一個(gè)Console.WriteLine("執(zhí)行判斷"),觀察這行代碼執(zhí)行多少次。從結(jié)果來(lái)看,實(shí)例化對(duì)象只執(zhí)行了一次,說(shuō)明對(duì)象只被創(chuàng)建過一次,滿足了我們的需求,達(dá)到了預(yù)期的效果。Version3-雙if+lock實(shí)現(xiàn)上面那種方式已經(jīng)可以達(dá)到預(yù)期效果,但是我們注意到一個(gè)問題,執(zhí)行判斷這行代碼被執(zhí)行了10次,這顯示不符合我們的邏輯,既然已經(jīng)實(shí)例化了,為什么每次還要執(zhí)行判斷呢?是不是多此一舉?并且每次請(qǐng)求對(duì)象,都會(huì)進(jìn)行l(wèi)ock操作,lock對(duì)性能是有一定影響的。于是我們繼續(xù)優(yōu)化,優(yōu)化之后的代碼如下:
publicclassChina
{
private
China()
{
}
privatestaticChinachina
=
null;
privatestaticobjectobjlock
=
newobject();
publicstaticChinaInstance
{
get
{
if
(china
==
null)
{
lock
(objlock)
{
Console.WriteLine("執(zhí)行判斷");
if
(china
==
null)
{
Console.WriteLine("實(shí)例化對(duì)象");
china
=
newChina();
}
}
}
return
china;
}
}
}我們對(duì)比代碼可以看出,就是又加了一個(gè)if(china==null),這種雙if+lock的方式,是不是可以解決我們的問題呢?我們執(zhí)行一次,看看結(jié)果:我們通過結(jié)果可以看到只執(zhí)行了一次判斷,也只執(zhí)行一次實(shí)例化對(duì)象,但是我們還可以繼續(xù)優(yōu)化。Version4-靜態(tài)變量實(shí)現(xiàn)話不多說(shuō),直接上代碼:
publicclassChina
{
private
China()
{
}
privatestatic
readonly
Chinachina
=
newChina();
publicstaticChinaInstance
{
get
{
return
china;
}
}
}利用靜態(tài)變量去實(shí)現(xiàn)單例,非常簡(jiǎn)單,但同時(shí)也是線程安全的,由CLR保證,在程序第一次使用該類之前被調(diào)用,而且只調(diào)用一次。但是這種方式也有缺點(diǎn),就是實(shí)例化過程是在程序初始化時(shí)就執(zhí)行的,而不是在使用時(shí)才執(zhí)行,就是說(shuō),不管你用不用,都已經(jīng)實(shí)例化了。Version5-完全懶漢式實(shí)現(xiàn)
publicclassChina
{
private
China()
{
}
publicstaticChinaInstance
{
get
{
return
Lazy.instance;
}
}
privateclassLazy
{
static
Lazy()
{
}
internalstatic
readonly
Chinainstance
=
newChina();
}
}這種方法與上一種方法類似,只是多加了一個(gè)類,來(lái)解決上一個(gè)版本的缺點(diǎn)。Version6-使用Lazy特性從.NET4開始,可以使用Lazytype來(lái)實(shí)現(xiàn)完全懶漢式,代碼也變得更簡(jiǎn)單,代碼如下:
publicclassChina
{
private
China()
{
}
privatestatic
readonly
Lazy<China>
lazy
=
newLazy<China>(()
=>
newChina());
publicstaticChinaInstance
{
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 電梯井施工后期驗(yàn)收方案
- 倉(cāng)庫(kù)屋頂分布式電站建設(shè)方案
- 實(shí)驗(yàn)室安全演練實(shí)施方案
- 2024高考化學(xué)一輪復(fù)習(xí)第十二章有機(jī)化學(xué)基礎(chǔ)第40講醛羧酸酯學(xué)案
- 2024年專用版鋼筋訂購(gòu)協(xié)議
- 安徽省蕪湖市2023-2024學(xué)年高一上學(xué)期期末考試 數(shù)學(xué) 含解析
- 2024年個(gè)人借款合同及還款協(xié)議
- 北京市海淀區(qū)2023-2024學(xué)年高二下學(xué)期期末考試數(shù)學(xué)試卷 含答案
- 移動(dòng)電子商務(wù)學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 地源熱泵在游泳池中的應(yīng)用方案
- 華電人才測(cè)評(píng)試題在線測(cè)試
- 《帶壓堵漏技術(shù)》課件
- 銅礦礦山規(guī)劃與布局
- 備考2023高考語(yǔ)文二輪 高中語(yǔ)文 山水田園類詩(shī)歌閱讀專項(xiàng)練習(xí)(解析)
- 人教版二年級(jí)上冊(cè)口算練習(xí)1000題及答案
- 2024年浙江建銀工程咨詢有限責(zé)任公司招聘筆試參考題庫(kù)含答案解析
- 醫(yī)院感染管理培訓(xùn)課件消毒劑的選擇與使用
- 平臺(tái)分銷返傭合作協(xié)議
- 水痘護(hù)理課件
- 肩關(guān)節(jié)鏡術(shù)的健康宣教
- 2024年廣西鋁業(yè)集團(tuán)有限公司招聘筆試參考題庫(kù)附帶答案詳解
評(píng)論
0/150
提交評(píng)論