www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀] 本文繼續(xù)介紹23種設(shè)計(jì)模式系列之單例模式。 概念:  Java中單例模式是一種常見(jiàn)的設(shè)計(jì)模式,單例模式的寫(xiě)法有好幾種,這里主要介紹三種:懶漢式單例、餓漢式單例、登記式單例?! 卫J接幸韵绿攸c(diǎn)

本文繼續(xù)介紹23種設(shè)計(jì)模式系列之單例模式。

概念:
  Java中單例模式是一種常見(jiàn)的設(shè)計(jì)模式,單例模式的寫(xiě)法有好幾種,這里主要介紹三種:懶漢式單例、餓漢式單例、登記式單例。
  單例模式有以下特點(diǎn):
  1、單例類(lèi)只能有一個(gè)實(shí)例。
  2、單例類(lèi)必須自己創(chuàng)建自己的唯一實(shí)例。
  3、單例類(lèi)必須給所有其他對(duì)象提供這一實(shí)例。
  單例模式確保某個(gè)類(lèi)只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。在計(jì)算機(jī)系統(tǒng)中,線程池、緩存、日志對(duì)象、對(duì)話框、打印機(jī)、顯卡的驅(qū)動(dòng)程序?qū)ο蟪1辉O(shè)計(jì)成單例。這些應(yīng)用都或多或少具有資源管理器的功能。每臺(tái)計(jì)算機(jī)可以有若干個(gè)打印機(jī),但只能有一個(gè)Printer Spooler,以避免兩個(gè)打印作業(yè)同時(shí)輸出到打印機(jī)中。每臺(tái)計(jì)算機(jī)可以有若干通信端口,系統(tǒng)應(yīng)當(dāng)集中管理這些通信端口,以避免一個(gè)通信端口同時(shí)被兩個(gè)請(qǐng)求同時(shí)調(diào)用??傊?,選擇單例模式就是為了避免不一致?tīng)顟B(tài),避免政出多頭。


一、懶漢式單例

[java]?view plain?copy ?print? //懶漢式單例類(lèi).在第一次調(diào)用的時(shí)候?qū)嵗约??? public?class?Singleton?{?? ????private?Singleton()?{}?? ????private?static?Singleton?single=null;?? ????//靜態(tài)工廠方法??? ????public?static?Singleton?getInstance()?{?? ?????????if?(single?==?null)?{???? ?????????????single?=?new?Singleton();?? ?????????}???? ????????return?single;?? ????}?? }??
Singleton通過(guò)將構(gòu)造方法限定為private避免了類(lèi)在外部被實(shí)例化,在同一個(gè)虛擬機(jī)范圍內(nèi),Singleton的唯一實(shí)例只能通過(guò)getInstance()方法訪問(wèn)。

(事實(shí)上,通過(guò)Java反射機(jī)制是能夠?qū)嵗瘶?gòu)造方法為private的類(lèi)的,那基本上會(huì)使所有的Java單例實(shí)現(xiàn)失效。此問(wèn)題在此處不做討論,姑且掩耳盜鈴地認(rèn)為反射機(jī)制不存在。)

但是以上懶漢式單例的實(shí)現(xiàn)沒(méi)有考慮線程安全問(wèn)題,它是線程不安全的,并發(fā)環(huán)境下很可能出現(xiàn)多個(gè)Singleton實(shí)例,要實(shí)現(xiàn)線程安全,有以下三種方式,都是對(duì)getInstance這個(gè)方法改造,保證了懶漢式單例的線程安全,如果你第一次接觸單例模式,對(duì)線程安全不是很了解,可以先跳過(guò)下面這三小條,去看餓漢式單例,等看完后面再回頭考慮線程安全的問(wèn)題:


1、在getInstance方法上加同步

[java]?view plain?copy ?print? public?static?synchronized?Singleton?getInstance()?{?? ?????????if?(single?==?null)?{???? ?????????????single?=?new?Singleton();?? ?????????}???? ????????return?single;?? }??

2、雙重檢查鎖定

[java]?view plain?copy ?print? public?static?Singleton?getInstance()?{?? ????????if?(singleton?==?null)?{???? ????????????synchronized?(Singleton.class)?{???? ???????????????if?(singleton?==?null)?{???? ??????????????????singleton?=?new?Singleton();??? ???????????????}???? ????????????}???? ????????}???? ????????return?singleton;??? ????}??

3、靜態(tài)內(nèi)部類(lèi)

[java]?view plain?copy ?print? public?class?Singleton?{???? ????private?static?class?LazyHolder?{???? ???????private?static?final?Singleton?INSTANCE?=?new?Singleton();???? ????}???? ????private?Singleton?(){}???? ????public?static?final?Singleton?getInstance()?{???? ???????return?LazyHolder.INSTANCE;???? ????}???? }???? 這種比上面1、2都好一些,既實(shí)現(xiàn)了線程安全,又避免了同步帶來(lái)的性能影響。


二、餓漢式單例

[java]?view plain?copy ?print? //餓漢式單例類(lèi).在類(lèi)初始化時(shí),已經(jīng)自行實(shí)例化??? public?class?Singleton1?{?? ????private?Singleton1()?{}?? ????private?static?final?Singleton1?single?=?new?Singleton1();?? ????//靜態(tài)工廠方法??? ????public?static?Singleton1?getInstance()?{?? ????????return?single;?? ????}?? }?? 餓漢式在類(lèi)創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對(duì)象供系統(tǒng)使用,以后不再改變,所以天生是線程安全的。

三、登記式單例(可忽略)

[java]?view plain?copy ?print? //類(lèi)似Spring里面的方法,將類(lèi)名注冊(cè),下次從里面直接獲取。?? public?class?Singleton3?{?? ????private?static?Map?map?=?new?HashMap();?? ????static{?? ????????Singleton3?single?=?new?Singleton3();?? ????????map.put(single.getClass().getName(),?single);?? ????}?? ????//保護(hù)的默認(rèn)構(gòu)造子?? ????protected?Singleton3(){}?? ????//靜態(tài)工廠方法,返還此類(lèi)惟一的實(shí)例?? ????public?static?Singleton3?getInstance(String?name)?{?? ????????if(name?==?null)?{?? ????????????name?=?Singleton3.class.getName();?? ????????????System.out.println("name?==?null"+"--->name="+name);?? ????????}?? ????????if(map.get(name)?==?null)?{?? ????????????try?{?? ????????????????map.put(name,?(Singleton3)?Class.forName(name).newInstance());?? ????????????}?catch?(InstantiationException?e)?{?? ????????????????e.printStackTrace();?? ????????????}?catch?(IllegalAccessException?e)?{?? ????????????????e.printStackTrace();?? ????????????}?catch?(ClassNotFoundException?e)?{?? ????????????????e.printStackTrace();?? ????????????}?? ????????}?? ????????return?map.get(name);?? ????}?? ????//一個(gè)示意性的商業(yè)方法?? ????public?String?about()?{?????? ????????return?"Hello,?I?am?RegSingleton.";?????? ????}?????? ????public?static?void?main(String[]?args)?{?? ????????Singleton3?single3?=?Singleton3.getInstance(null);?? ????????System.out.println(single3.about());?? ????}?? }??

?登記式單例實(shí)際上維護(hù)了一組單例類(lèi)的實(shí)例,將這些實(shí)例存放在一個(gè)Map(登記?。┲?,對(duì)于已經(jīng)登記過(guò)的實(shí)例,則從Map直接返回,對(duì)于沒(méi)有登記的,則先登記,然后返回。?

這里我對(duì)登記式單例標(biāo)記了可忽略,我的理解來(lái)說(shuō),首先它用的比較少,另外其實(shí)內(nèi)部實(shí)現(xiàn)還是用的餓漢式單例,因?yàn)槠渲械膕tatic方法塊,它的單例在類(lèi)被裝載的時(shí)候就被實(shí)例化了。


餓漢式和懶漢式區(qū)別

從名字上來(lái)說(shuō),餓漢和懶漢,

餓漢就是類(lèi)一旦加載,就把單例初始化完成,保證getInstance的時(shí)候,單例是已經(jīng)存在的了,

而懶漢比較懶,只有當(dāng)調(diào)用getInstance的時(shí)候,才回去初始化這個(gè)單例。

另外從以下兩點(diǎn)再區(qū)分以下這兩種方式:


1、線程安全:

餓漢式天生就是線程安全的,可以直接用于多線程而不會(huì)出現(xiàn)問(wèn)題,

懶漢式本身是非線程安全的,為了實(shí)現(xiàn)線程安全有幾種寫(xiě)法,分別是上面的1、2、3,這三種實(shí)現(xiàn)在資源加載和性能方面有些區(qū)別。



2、資源加載和性能:

餓漢式在類(lèi)創(chuàng)建的同時(shí)就實(shí)例化一個(gè)靜態(tài)對(duì)象出來(lái),不管之后會(huì)不會(huì)使用這個(gè)單例,都會(huì)占據(jù)一定的內(nèi)存,但是相應(yīng)的,在第一次調(diào)用時(shí)速度也會(huì)更快,因?yàn)槠滟Y源已經(jīng)初始化完成,

而懶漢式顧名思義,會(huì)延遲加載,在第一次使用該單例的時(shí)候才會(huì)實(shí)例化對(duì)象出來(lái),第一次調(diào)用時(shí)要做初始化,如果要做的工作比較多,性能上會(huì)有些延遲,之后就和餓漢式一樣了。

至于1、2、3這三種實(shí)現(xiàn)又有些區(qū)別,

第1種,在方法調(diào)用上加了同步,雖然線程安全了,但是每次都要同步,會(huì)影響性能,畢竟99%的情況下是不需要同步的,

第2種,在getInstance中做了兩次null檢查,確保了只有第一次調(diào)用單例的時(shí)候才會(huì)做同步,這樣也是線程安全的,同時(shí)避免了每次都同步的性能損耗

第3種,利用了classloader的機(jī)制來(lái)保證初始化instance時(shí)只有一個(gè)線程,所以也是線程安全的,同時(shí)沒(méi)有性能損耗,所以一般我傾向于使用這一種。


什么是線程安全?

如果你的代碼所在的進(jìn)程中有多個(gè)線程在同時(shí)運(yùn)行,而這些線程可能會(huì)同時(shí)運(yùn)行這段代碼。如果每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,而且其他的變量的值也和預(yù)期的是一樣的,就是線程安全的。

或者說(shuō):一個(gè)類(lèi)或者程序所提供的接口對(duì)于線程來(lái)說(shuō)是原子操作,或者多個(gè)線程之間的切換不會(huì)導(dǎo)致該接口的執(zhí)行結(jié)果存在二義性,也就是說(shuō)我們不用考慮同步的問(wèn)題,那就是線程安全的。


應(yīng)用

以下是一個(gè)單例類(lèi)使用的例子,以懶漢式為例,這里為了保證線程安全,使用了雙重檢查鎖定的方式:

[java]?view plain?copy ?print? public?class?TestSingleton?{?? ????String?name?=?null;?? ?? ????????private?TestSingleton()?{?? ????}?? ?? ????private?static?volatile?TestSingleton?instance?=?null;?? ?? ????public?static?TestSingleton?getInstance()?{?? ???????????if?(instance?==?null)?{???? ?????????????synchronized?(TestSingleton.class)?{???? ????????????????if?(instance?==?null)?{???? ???????????????????instance?=?new?TestSingleton();??? ????????????????}???? ?????????????}???? ???????????}??? ???????????return?instance;?? ????}?? ?? ????public?String?getName()?{?? ????????return?name;?? ????}?? ?? ????public?void?setName(String?name)?{?? ????????this.name?=?name;?? ????}?? ?? ????public?void?printInfo()?{?? ????????System.out.println("the?name?is?"?+?name);?? ????}?? ?? }??

可以看到里面加了volatile關(guān)鍵字來(lái)聲明單例對(duì)象,既然synchronized已經(jīng)起到了多線程下原子性、有序性、可見(jiàn)性的作用,為什么還要加volatile呢,原因已經(jīng)在下面評(píng)論中提到,

還有疑問(wèn)可參考http://www.iteye.com/topic/652440
和http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html


[java]?view plain?copy ?print? public?class?TMain?{?? ????public?static?void?main(String[]?args){?? ????????TestStream?ts1?=?TestSingleton.getInstance();?? ????????ts1.setName("jason");?? ????????TestStream?ts2?=?TestSingleton.getInstance();?? ????????ts2.setName("0539");?? ?????????? ????????ts1.printInfo();?? ????????ts2.printInfo();?? ?????????? ????????if(ts1?==?ts2){?? ????????????System.out.println("創(chuàng)建的是同一個(gè)實(shí)例");?? ????????}else{?? ????????????System.out.println("創(chuàng)建的不是同一個(gè)實(shí)例");?? ????????}?? ????}?? }??

?運(yùn)行結(jié)果:


結(jié)論:由結(jié)果可以得知單例模式為一個(gè)面向?qū)ο蟮膽?yīng)用程序提供了對(duì)象惟一的訪問(wèn)點(diǎn),不管它實(shí)現(xiàn)何種功能,整個(gè)應(yīng)用程序都會(huì)同享一個(gè)實(shí)例對(duì)象。

對(duì)于單例模式的幾種實(shí)現(xiàn)方式,知道餓漢式和懶漢式的區(qū)別,線程安全,資源加載的時(shí)機(jī),還有懶漢式為了實(shí)現(xiàn)線程安全的3種方式的細(xì)微差別。



更多設(shè)計(jì)模式:23種設(shè)計(jì)模式系列


作者:jason0539

博客:http://blog.csdn.net/jason0539(轉(zhuǎn)載請(qǐng)說(shuō)明出處)




本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉