Java單例模式的深入了解_第1頁(yè)
Java單例模式的深入了解_第2頁(yè)
Java單例模式的深入了解_第3頁(yè)
Java單例模式的深入了解_第4頁(yè)
Java單例模式的深入了解_第5頁(yè)
已閱讀5頁(yè),還剩3頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第Java單例模式的深入了解實(shí)際上,這些原則的目的只有一個(gè):降低對(duì)象之間的耦合,增加程序的可復(fù)用性、可擴(kuò)展性和可維護(hù)性。

記憶口訣:訪問(wèn)加限制,函數(shù)要節(jié)儉,依賴不允許,動(dòng)態(tài)加接口,父類要抽象,擴(kuò)展不更改。

在程序設(shè)計(jì)時(shí),我們應(yīng)該將程序功能最小化,每個(gè)類只干一件事。若有類似功能基礎(chǔ)之上添加新功能,則要合理使用繼承。對(duì)于多方法的調(diào)用,要會(huì)運(yùn)用接口,同時(shí)合理設(shè)置接口功能與數(shù)量。最后類與類之間做到低耦合高內(nèi)聚。

二、單利模式

1.1、單例模式的相關(guān)定義

指一個(gè)類只有一個(gè)實(shí)例,且該類能自行創(chuàng)建這個(gè)實(shí)例的一種模式。例如,Windows中只能打開(kāi)一個(gè)任務(wù)管理器,這樣可以避免因打開(kāi)多個(gè)任務(wù)管理器窗口而造成內(nèi)存資源的浪費(fèi),或出現(xiàn)各個(gè)窗口顯示內(nèi)容的不一致等錯(cuò)誤。

單利模式三個(gè)特點(diǎn)

單例類只有一個(gè)實(shí)例對(duì)象;

該單例對(duì)象必須由單例類自行創(chuàng)建;

單例類對(duì)外提供一個(gè)訪問(wèn)該單例的全局訪問(wèn)點(diǎn)。

單例模式的優(yōu)點(diǎn)

單例模式可以保證內(nèi)存里只有一個(gè)實(shí)例,減少了內(nèi)存的開(kāi)銷。

可以避免對(duì)資源的多重占用。

單例模式設(shè)置全局訪問(wèn)點(diǎn),可以優(yōu)化和共享資源的訪問(wèn)。

單例模式的缺點(diǎn):

單例模式一般沒(méi)有接口,擴(kuò)展困難。如果要擴(kuò)展,則除了修改原來(lái)的代碼,沒(méi)有第二種途徑,違背開(kāi)閉原則。

在并發(fā)測(cè)試中,單例模式不利于代碼調(diào)試。在調(diào)試過(guò)程中,如果單例中的代碼沒(méi)有執(zhí)行完,也不能模擬生成一個(gè)新的對(duì)象。

單例模式的功能代碼通常寫(xiě)在一個(gè)類中,如果功能設(shè)計(jì)不合理,則很容易違背單一職責(zé)原則。

單例模式的應(yīng)用場(chǎng)景

需要頻繁創(chuàng)建的一些類,使用單例可以降低系統(tǒng)的內(nèi)存壓力,減少GC。

某類只要求生成一個(gè)對(duì)象的時(shí)候,如一個(gè)班中的班長(zhǎng)、每個(gè)人的身份證號(hào)等。

某些類創(chuàng)建實(shí)例時(shí)占用資源較多,或?qū)嵗臅r(shí)較長(zhǎng),且經(jīng)常使用。

某類需要頻繁實(shí)例化,而創(chuàng)建的對(duì)象又頻繁被銷毀的時(shí)候,如多線程的線程池、網(wǎng)絡(luò)連接池等。

頻繁訪問(wèn)數(shù)據(jù)庫(kù)或文件的對(duì)象。

對(duì)于一些控制硬件級(jí)別的操作,或者從系統(tǒng)上來(lái)講應(yīng)當(dāng)是單一控制邏輯的操作,如果有多個(gè)實(shí)例,則系統(tǒng)會(huì)完全亂套。

當(dāng)對(duì)象需要被共享的場(chǎng)合。由于單例模式只允許創(chuàng)建一個(gè)對(duì)象,共享該對(duì)象可以節(jié)省內(nèi)存,并加快對(duì)象訪問(wèn)速度。如Web中的配置對(duì)象、數(shù)據(jù)庫(kù)的連接池等。

1.2、單利模式的結(jié)構(gòu)

單例類:包含一個(gè)實(shí)例且能自行創(chuàng)建這個(gè)實(shí)例的類。

訪問(wèn)類:使用單例的類。

2.1單利模式的實(shí)現(xiàn)方式一:懶漢式

該模式的特點(diǎn)是類加載時(shí)沒(méi)有生成單例,只有當(dāng)?shù)谝淮握{(diào)用getlnstance方法時(shí)才去創(chuàng)建這個(gè)單例。

代碼:

publicclassLazySingleton{

//構(gòu)造器私有,堵死了外界利用new創(chuàng)建此類對(duì)象的可能

privateLazySingleton(){

System.out.println(yese

//提供對(duì)象,是外界獲取本類對(duì)象的唯一全局訪問(wèn)點(diǎn)

privatestaticLazySingletonlazySingleton;

publicstaticLazySingletongetInstance(){

//如果對(duì)象不存在,就new一個(gè)新的對(duì)象,否則返回已有的對(duì)象

if(lazySingleton==null){

lazySingleton=newLazySingleton();

returnlazySingleton;

}

@Test

publicvoidtestLazy(){

LazySingletonl1=LazySingleton.getInstance();

LazySingletonl2=LazySingleton.getInstance();

System.out.println(l1+\n+l2);

System.out.println(l1==l2);

}

測(cè)試結(jié)果:

com.singletonPattern.LazySingleton@78e03bb5

com.singletonPattern.LazySingleton@78e03bb5

true

該代碼很顯然是不適合多線程模式的,這時(shí)候就需要給單例模式的對(duì)象加上一把鎖

classLazySingleton2{

//構(gòu)造器私有,堵死了外界利用new創(chuàng)建此類對(duì)象的可能

privateLazySingleton2(){

System.out.println(s2

//提供對(duì)象,是外界獲取本類對(duì)象的唯一全局訪問(wèn)點(diǎn)

privatestaticLazySingleton2lazySingleton2;

publicstaticLazySingleton2getInstance(){

//如果對(duì)象不存在,就new一個(gè)新的對(duì)象,否則返回已有的對(duì)象

if(lazySingleton2==null){

synchronized(LazySingleton2.class){

if(lazySingleton2==null){

lazySingleton2=newLazySingleton2();

returnlazySingleton2;

}

這時(shí)還有一個(gè)問(wèn)題,就是在創(chuàng)建一個(gè)對(duì)象時(shí),在JVM中會(huì)經(jīng)過(guò)三步:

(1)為對(duì)象分配內(nèi)存空間

(2)初始化該對(duì)象

(3)將該對(duì)象指向分配好的內(nèi)存空間

那么在執(zhí)行我們這個(gè)多線程代碼的過(guò)程中,有可能他不按照這三部的順序走,那么就會(huì)導(dǎo)致一個(gè)指令重排的問(wèn)題,解決此問(wèn)題的方法就是加關(guān)鍵字volatile

classLazySingleton3{

//構(gòu)造器私有,堵死了外界利用new創(chuàng)建此類對(duì)象的可能

privateLazySingleton3(){

//提供對(duì)象,是外界獲取本類對(duì)象的唯一全局訪問(wèn)點(diǎn)

privatevolatilestaticLazySingleton3lazySingleton3;

publicstaticLazySingleton3getInstance(){

//如果對(duì)象不存在,就new一個(gè)新的對(duì)象,否則返回已有的對(duì)象

if(lazySingleton3==null){

synchronized(LazySingleton3.class){

if(lazySingleton3==null){

lazySingleton3=newLazySingleton3();

returnlazySingleton3;

}

最后我們還可以去解決一下反射來(lái)破壞單利模式

classLazySingleton4{

//提供變量,控制反射

publicstaticbooleans=false;

//構(gòu)造器私有,堵死了外界利用new創(chuàng)建此類對(duì)象的可能

privateLazySingleton4(){

if(s==false){

//當(dāng)?shù)谝粋€(gè)對(duì)象成功獲取之后,第二個(gè)對(duì)象就不能通過(guò)反射獲取了

s=true;

}else{

thrownewRuntimeException(不要用反射破壞異常

//提供對(duì)象,是外界獲取本類對(duì)象的唯一全局訪問(wèn)點(diǎn)

privatevolatilestaticLazySingleton4lazySingleton4;

publicstaticLazySingleton4getInstance(){

//如果對(duì)象不存在,就new一個(gè)新的對(duì)象,否則返回已有的對(duì)象

if(lazySingleton4==null){

synchronized(LazySingleton4.class){

if(lazySingleton4==null){

lazySingleton4=newLazySingleton4();

returnlazySingleton4;

}

volatile,synchronized這兩個(gè)關(guān)鍵字就能保證線程安全,但是每次訪問(wèn)時(shí)都要同步,會(huì)影響性能,且消耗更多的資源,這是懶漢式單例的缺點(diǎn)。

2.2單利模式的實(shí)現(xiàn)方式一:餓漢式

該模式的特點(diǎn)是類一旦加載就創(chuàng)建一個(gè)單例,保證在調(diào)用getInstance方法之前單例已經(jīng)存在了。

代碼:

publicclassHungrySingleton{

privatestaticfinalHungrySingletoninstance=newHungrySingleton();

privateHung

溫馨提示

  • 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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論