日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > > 充電吧
[導(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)中,線(xiàn)程池、緩存、日志對(duì)象、對(duì)話(huà)框、打印機(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)工廠(chǎng)方法??? ????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()方法訪(fǎng)問(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)有考慮線(xiàn)程安全問(wèn)題,它是線(xiàn)程不安全的,并發(fā)環(huán)境下很可能出現(xiàn)多個(gè)Singleton實(shí)例,要實(shí)現(xiàn)線(xiàn)程安全,有以下三種方式,都是對(duì)getInstance這個(gè)方法改造,保證了懶漢式單例的線(xiàn)程安全,如果你第一次接觸單例模式,對(duì)線(xiàn)程安全不是很了解,可以先跳過(guò)下面這三小條,去看餓漢式單例,等看完后面再回頭考慮線(xiàn)程安全的問(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)了線(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)工廠(chǎng)方法??? ????public?static?Singleton1?getInstance()?{?? ????????return?single;?? ????}?? }?? 餓漢式在類(lèi)創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對(duì)象供系統(tǒng)使用,以后不再改變,所以天生是線(xiàn)程安全的。

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

[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)工廠(chǎng)方法,返還此類(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、線(xiàn)程安全:

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

懶漢式本身是非線(xiàn)程安全的,為了實(shí)現(xiàn)線(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)用上加了同步,雖然線(xiàn)程安全了,但是每次都要同步,會(huì)影響性能,畢竟99%的情況下是不需要同步的,

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

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


什么是線(xiàn)程安全?

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

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


應(yīng)用

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

[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)起到了多線(xiàn)程下原子性、有序性、可見(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ì)象惟一的訪(fǎng)問(wèn)點(diǎn),不管它實(shí)現(xiàn)何種功能,整個(gè)應(yīng)用程序都會(huì)同享一個(gè)實(shí)例對(duì)象。

對(duì)于單例模式的幾種實(shí)現(xiàn)方式,知道餓漢式和懶漢式的區(qū)別,線(xiàn)程安全,資源加載的時(shí)機(jī),還有懶漢式為了實(shí)現(xiàn)線(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ā)布,目的在于傳遞更多信息,并不代表本站贊同其觀(guān)點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶(hù)體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(chē)(EV)作為新能源汽車(chē)的重要代表,正逐漸成為全球汽車(chē)產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車(chē)的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車(chē)的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車(chē) 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車(chē)場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周?chē)娮釉O(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉