版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
結(jié)合這三點(diǎn),我們來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單代碼//餓漢模publicfinalclassSingletonprivatestaticSingletoninstance=newSingleton();//自行創(chuàng)建實(shí)privateSingleton(){}//構(gòu)造函publicstaticSingletongetInstance(){//通過(guò)該函數(shù)向整個(gè)系統(tǒng)提供return 8我們可以發(fā)現(xiàn),以上第一種實(shí)現(xiàn)單例的代碼中,使用了static了成員instance,所以該變量會(huì)在類(lèi)初始化的過(guò)程中被收集進(jìn)類(lèi)構(gòu)造器即<clinit>方法中。在多線程場(chǎng)景下,JVM會(huì)保證只有一個(gè)線程能執(zhí)行該類(lèi)的<clinit>方法,其它線程將會(huì)被阻塞等待。等到唯一的一次<clinit>方法執(zhí)行完成,其它線程將不會(huì)再執(zhí)行<clinit>方法,轉(zhuǎn)而執(zhí)行自己的代碼。也就是說(shuō),static修飾了成員變量instance,在多線程的情況下能保證只實(shí)餓漢模式實(shí)現(xiàn)的單例的優(yōu)點(diǎn)是,可以保證多線程情況下實(shí)例的唯一性,而且直接返回唯一實(shí)例,性能非情況下,一直占用堆內(nèi)存。試想下,如果一個(gè)第開(kāi)源框架中的類(lèi)都是基于餓漢模式實(shí)的單例,這將會(huì)初始化所有單例類(lèi),無(wú)疑是性的懶漢模式就是為了避免直接加載類(lèi)對(duì)象時(shí)提前創(chuàng)建對(duì)象的一種單例設(shè)計(jì)模式。該模式使用懶加載方式,只有當(dāng)系統(tǒng)使用到類(lèi)對(duì)象時(shí),才會(huì)將實(shí)例加載到堆內(nèi)存中。通過(guò)以下代碼,我們可以簡(jiǎn)單地了解下懶加載的實(shí)現(xiàn)方式:代碼//懶漢模publicfinalclassSingletonprivatestaticSingletoninstance=null;//不實(shí)例privateSingleton(){}//構(gòu)造函publicstaticSingletongetInstance(){//通過(guò)該函數(shù)向整個(gè)系統(tǒng)提供if(null==instance){//當(dāng)instance為null時(shí),則實(shí)例化對(duì)象,否則直接返回instance=newSingleton();//實(shí)例化對(duì) returninstance;//返回已存在的 11當(dāng)線程A入到if斷條件后,開(kāi)始實(shí)例化對(duì)象,此時(shí)instance然為null;又有線程B進(jìn)入到if判斷條件中,之后也會(huì)通過(guò)條件判斷,進(jìn)入到方法里面創(chuàng)建一個(gè)實(shí)例對(duì)象。所以我們需要對(duì)該方法進(jìn)行加鎖,保證多線程情況下僅創(chuàng)建一個(gè)實(shí)例。這里我們使Synchronized鎖來(lái)修飾getInstance法代碼//懶漢模式+synchronized同步publicfinalclassSingletonprivatestaticSingletoninstance=null;//不實(shí)例privateSingleton(){}//構(gòu)造函publicstaticsynchronizedSingletongetInstance(){//加同步鎖,通過(guò)該函數(shù)向整個(gè)系if(null==instance){//當(dāng)instance為null時(shí),則實(shí)例化對(duì)象,否則直接返回instance=newSingleton();//實(shí)例化對(duì) returninstance;//返回已存在的 11還有,每次請(qǐng)求獲取類(lèi)對(duì)象時(shí),都會(huì)通過(guò)getInstance()方法獲取,除了第一次為l它每次請(qǐng)求基本都是不為l的。在沒(méi)有加同步鎖之前,是因?yàn)閒判斷條件為l導(dǎo)致創(chuàng)建了多個(gè)實(shí)例。基于以上兩點(diǎn),我們可以考慮將同步鎖放在f條件里面,這樣就可以減少同步鎖資源競(jìng)爭(zhēng)。代碼//懶漢模式+synchronized同步publicfinalclassSingletonprivatestaticSingletoninstance=null;//不實(shí)例privateSingleton(){}//構(gòu)造函publicstaticSingletongetInstance(){//加同步鎖,通過(guò)該函數(shù)向整個(gè)系統(tǒng)提供if(null==instance){//當(dāng)instance為null時(shí),則實(shí)例化對(duì)象,否則直接返回synchronizedinstance=newSingleton();//實(shí)例化對(duì) }returninstance;//返回已存在的 13if判斷條件里,雖然有同步鎖,但是進(jìn)入到判斷條件里面的線程依然會(huì)依次獲取到鎖創(chuàng)建對(duì)象,然后再釋放同步鎖。所以我們還需要在同步鎖里面再加一個(gè)判斷條件:代碼//懶漢模式+synchronized同步鎖+double-publicfinalclassSingletonprivatestaticSingletoninstance=null;//不實(shí)例privateSingleton(){}//構(gòu)造函publicstaticSingletongetInstance(){//加同步鎖,通過(guò)該函數(shù)向整個(gè)系統(tǒng)提供if(null==instance){//第一次判斷,當(dāng)instance為null時(shí),則實(shí)例化對(duì)象,否則直synchronized(Singleton.class){//同步if(null==instance){//第二次判9
instance=newSingleton();//實(shí)例化對(duì)}returninstance;//返回已存在的}}以上這種方式,通常被稱(chēng)為Double-Check,它可以大大提高支持多線程的懶漢模式的運(yùn)其實(shí)這里又跟Happens-Before規(guī)則和重排序扯上關(guān)系了,這里我們先來(lái)簡(jiǎn)單了解Happens-Before規(guī)則和重排序我們?cè)诘诙诓椭羞^(guò)譯器盡可減少器的、數(shù),分復(fù)用寄存器的值,比如以下代碼,如果沒(méi)有進(jìn)行重排序優(yōu)化,正常的執(zhí)行順序是步驟\\,而在編譯期間進(jìn)行了重排序優(yōu)化之后,執(zhí)行的步驟有可能就變成了步驟/2樣就能減少一次寄存器的存取次數(shù)。代碼inta=1;//步驟1:加載a變量的內(nèi)存地址到寄存器中,加載1到寄存器中,CPU通過(guò)mov指令intb=2;//步驟2加載b變量的內(nèi)存地址到寄存器中,加載2到寄存器中,CPU通過(guò)mov指令把a(bǔ)=a+1;//步驟3重新加載a變量的內(nèi)存地址到寄存器中,加載1到寄存器中,CPU通過(guò)mov在JMM中,重排序是十分重要的一環(huán),特別是在并發(fā)編程中。如果JVM任意排序以提高程序性能,也可能會(huì)給并發(fā)編程帶來(lái)一系列的問(wèn)題。例如,我上面講到的oub-Check的單例問(wèn)題,假設(shè)類(lèi)中有其它的屬性也需要實(shí)例化,這個(gè)時(shí)候,除了要實(shí)例化單例類(lèi)本身,還需要對(duì)其它屬性也進(jìn)行實(shí)例化:代碼//懶漢模式+synchronized同步鎖+double-publicfinalclassSingletonprivatestaticSingletoninstance=null;//不實(shí)例publicList<String>list=null;//list屬privatelist=new}//構(gòu)造函8918
publicstaticSingletongetInstance(){//加同步鎖,通過(guò)該函數(shù)向整個(gè)系統(tǒng)提供if(null==instance){//第一次判斷,當(dāng)instance為null時(shí),則實(shí)例化對(duì)象,否則直synchronized(Singleton.class){//同步if(null==instance){//第二次判instance=newSingleton();//實(shí)例化對(duì)}}}returninstance;//返回已存在的}在執(zhí)行instance=newSingleton();代碼時(shí),正常情況下,實(shí)例過(guò)程這樣給Singleton分配內(nèi)存調(diào)用Singleton的構(gòu)造函數(shù)來(lái)初始化成員變將Singleton對(duì)象指向分配的內(nèi)存空間(執(zhí)行完這步singleton就為非null了)如果虛擬機(jī)發(fā)生了重排序優(yōu)化,這個(gè)時(shí)候步驟3可能發(fā)生在步驟2之前。如果初始化線程剛好完成步驟3,而步驟2沒(méi)有進(jìn)行時(shí),則剛好有另一個(gè)線程到了第一次判斷,這個(gè)時(shí)候判斷為非null,并返回對(duì)象使用,這個(gè)時(shí)候?qū)嶋H沒(méi)有完成其它屬性的構(gòu)造,因此使用這個(gè)屬性就很可能會(huì)導(dǎo)致異常。在這里,Synchronized只能保證可見(jiàn)性、原子性,無(wú)法保證執(zhí)這個(gè)時(shí)候,就體現(xiàn)出Happens-Before規(guī)則的重要性了。通過(guò)字面意思,你可能會(huì)誤以為我們知道volatile關(guān)鍵字可以保證線程間變量的可見(jiàn)性,簡(jiǎn)單地說(shuō)就是當(dāng)線程A對(duì)變量X進(jìn)行修改后,程A后面執(zhí)行的其它線程就能看到變量X的變動(dòng)。除此之外,volatile在JDK1.5之后還有一個(gè)作用就是局部重排序的發(fā)生,也就是說(shuō),volatile變量的操作指令都不會(huì)被重排序。所以使用volatile修飾instance之后,Double-Check懶漢單例模代碼//懶漢模式+synchronized同步鎖+double-publicfinalclassSingletonprivatevolatilestaticSingletoninstance=null;//不實(shí)例publicList<String>list=null;//list屬private6list=new7}//構(gòu)造函8publicstaticSingletongetInstance(){//加同步鎖,通過(guò)該函數(shù)向整個(gè)系統(tǒng)提供9if(null==instance){//第一次判斷,當(dāng)instance為null時(shí),則實(shí)例化對(duì)象,否則直synchronized(Singleton.class){//同步if(null==instance){//第二次判instance=newSingleton();//實(shí)例化對(duì)}}}returninstance;//返回已存在的}}以上這種同步鎖+Double-Check實(shí)現(xiàn)方式相對(duì)來(lái)說(shuō),復(fù)雜且加了同步鎖,那有沒(méi)有稍我們知道,在餓漢模式中,我們使用了static修飾了成員變量instance,所以該變量會(huì)在類(lèi)初始化的過(guò)程中被收集進(jìn)類(lèi)構(gòu)造器即<clinit>方法中。在多線程場(chǎng)景下,JVM會(huì)保證只有一個(gè)線程能執(zhí)行該類(lèi)的<clinit>方法,其它線程將會(huì)被阻塞等待。這種方式可以保證內(nèi)如果我們?cè)赟ingleton類(lèi)中創(chuàng)建一個(gè)內(nèi)部類(lèi)來(lái)實(shí)現(xiàn)成員變量的初始化,則可以避免多線程下重復(fù)創(chuàng)建對(duì)象的情況發(fā)生。這種方式,只有在第一次調(diào)用getInstance()方法時(shí),才會(huì)加載InnerSingleton類(lèi),而只有在加載InnerSingleton類(lèi)之后,才會(huì)實(shí)例化創(chuàng)建對(duì)象。具代碼//懶漢模式內(nèi)部類(lèi)實(shí)publicfinalclassSingletonpublicList<String>list=null;//list屬4privateSingleton(){//構(gòu)造函list=new 8 //內(nèi)部類(lèi)17
publicstaticclassInnerSingletonprivatestaticSingletoninstance=newSingleton();//自行創(chuàng)建實(shí)}publicstaticSingletongetInstance()returnInnerSingleton.instance;//返回內(nèi)部類(lèi)中的靜態(tài)變}如果我們?cè)诔绦騿?dòng)后,一定會(huì)加載到類(lèi),那么用餓漢模式實(shí)現(xiàn)的單例簡(jiǎn)單又實(shí)用;如果我們是寫(xiě)一些工具類(lèi),則優(yōu)先考慮使用懶漢模式,因?yàn)楹芏囗?xiàng)目可能會(huì)到r,但未除了以上那些實(shí)現(xiàn)單例的方式,你還知道其它實(shí)現(xiàn)方 科技所有 不 售賣(mài)。頁(yè)面已增加防盜追蹤,將依 上一 25|答疑課堂:模塊四熱點(diǎn)問(wèn)題解下一 27|原型模式與享元模式:提升系統(tǒng)性能的利精選留言展9使用枚舉來(lái)實(shí)現(xiàn)單例模式,具體代碼如下:publicclass{privatestaticSinletonExample5instance=private展7相比DoubleCheck,以?xún)?nèi)部類(lèi)方式實(shí)現(xiàn)單例模式,代碼簡(jiǎn)潔,性能相近,在我看來(lái)是更優(yōu)展3展3方式和枚
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 年會(huì)活動(dòng)總結(jié)范文15篇
- 法治社會(huì)+學(xué)案 高中政治統(tǒng)編版必修三政治與法治
- 初級(jí)會(huì)計(jì)實(shí)務(wù)-《初級(jí)會(huì)計(jì)實(shí)務(wù)》預(yù)測(cè)試卷263
- 初級(jí)會(huì)計(jì)經(jīng)濟(jì)法基礎(chǔ)-初級(jí)會(huì)計(jì)《經(jīng)濟(jì)法基礎(chǔ)》??荚嚲?10
- 二氧化硅殼層微膠囊的制備及其復(fù)合材料自潤(rùn)滑性能研究
- 2025版稅務(wù)代理與合規(guī)服務(wù)合同范本9篇
- 二零二五年度產(chǎn)品發(fā)布會(huì)舞臺(tái)租賃與現(xiàn)場(chǎng)直播合同3篇
- 2025版陶佳離婚案子女撫養(yǎng)權(quán)及財(cái)產(chǎn)分配方案3篇
- 二零二五年度基礎(chǔ)設(shè)施投資擔(dān)保協(xié)議書(shū)3篇
- 二零二五年度個(gè)人房屋租賃合同范本全新版4篇
- 中國(guó)的世界遺產(chǎn)知到章節(jié)答案智慧樹(shù)2023年遼寧科技大學(xué)
- 道路通行能力手冊(cè)第4章-高速公路基本路段
- 傳感器與測(cè)試技術(shù)試卷及答案
- 2020年普通高等學(xué)校招生全國(guó)統(tǒng)一數(shù)學(xué)考試大綱
- 土方轉(zhuǎn)運(yùn)方案
- (11.3.1)-10.3蒸汽壓縮制冷循環(huán)
- GB/T 679-2002化學(xué)試劑乙醇(95%)
- 總則(養(yǎng)牛場(chǎng)環(huán)評(píng)報(bào)告)
- GB/T 21797-2008化學(xué)品有機(jī)磷化合物28天重復(fù)劑量的遲發(fā)性神經(jīng)毒性試驗(yàn)
- 旅游文本的翻譯課件
- 最全新能源材料-鋰離子電池材料189張課件
評(píng)論
0/150
提交評(píng)論