Java單例模式的深入了解_第1頁
Java單例模式的深入了解_第2頁
Java單例模式的深入了解_第3頁
Java單例模式的深入了解_第4頁
Java單例模式的深入了解_第5頁
已閱讀5頁,還剩3頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第Java單例模式的深入了解實際上,這些原則的目的只有一個:降低對象之間的耦合,增加程序的可復用性、可擴展性和可維護性。

記憶口訣:訪問加限制,函數要節儉,依賴不允許,動態加接口,父類要抽象,擴展不更改。

在程序設計時,我們應該將程序功能最小化,每個類只干一件事。若有類似功能基礎之上添加新功能,則要合理使用繼承。對于多方法的調用,要會運用接口,同時合理設置接口功能與數量。最后類與類之間做到低耦合高內聚。

二、單利模式

1.1、單例模式的相關定義

指一個類只有一個實例,且該類能自行創建這個實例的一種模式。例如,Windows中只能打開一個任務管理器,這樣可以避免因打開多個任務管理器窗口而造成內存資源的浪費,或出現各個窗口顯示內容的不一致等錯誤。

單利模式三個特點

單例類只有一個實例對象;

該單例對象必須由單例類自行創建;

單例類對外提供一個訪問該單例的全局訪問點。

單例模式的優點

單例模式可以保證內存里只有一個實例,減少了內存的開銷。

可以避免對資源的多重占用。

單例模式設置全局訪問點,可以優化和共享資源的訪問。

單例模式的缺點:

單例模式一般沒有接口,擴展困難。如果要擴展,則除了修改原來的代碼,沒有第二種途徑,違背開閉原則。

在并發測試中,單例模式不利于代碼調試。在調試過程中,如果單例中的代碼沒有執行完,也不能模擬生成一個新的對象。

單例模式的功能代碼通常寫在一個類中,如果功能設計不合理,則很容易違背單一職責原則。

單例模式的應用場景

需要頻繁創建的一些類,使用單例可以降低系統的內存壓力,減少GC。

某類只要求生成一個對象的時候,如一個班中的班長、每個人的身份證號等。

某些類創建實例時占用資源較多,或實例化耗時較長,且經常使用。

某類需要頻繁實例化,而創建的對象又頻繁被銷毀的時候,如多線程的線程池、網絡連接池等。

頻繁訪問數據庫或文件的對象。

對于一些控制硬件級別的操作,或者從系統上來講應當是單一控制邏輯的操作,如果有多個實例,則系統會完全亂套。

當對象需要被共享的場合。由于單例模式只允許創建一個對象,共享該對象可以節省內存,并加快對象訪問速度。如Web中的配置對象、數據庫的連接池等。

1.2、單利模式的結構

單例類:包含一個實例且能自行創建這個實例的類。

訪問類:使用單例的類。

2.1單利模式的實現方式一:懶漢式

該模式的特點是類加載時沒有生成單例,只有當第一次調用getlnstance方法時才去創建這個單例。

代碼:

publicclassLazySingleton{

//構造器私有,堵死了外界利用new創建此類對象的可能

privateLazySingleton(){

System.out.println(yese

//提供對象,是外界獲取本類對象的唯一全局訪問點

privatestaticLazySingletonlazySingleton;

publicstaticLazySingletongetInstance(){

//如果對象不存在,就new一個新的對象,否則返回已有的對象

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);

}

測試結果:

com.singletonPattern.LazySingleton@78e03bb5

com.singletonPattern.LazySingleton@78e03bb5

true

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

classLazySingleton2{

//構造器私有,堵死了外界利用new創建此類對象的可能

privateLazySingleton2(){

System.out.println(s2

//提供對象,是外界獲取本類對象的唯一全局訪問點

privatestaticLazySingleton2lazySingleton2;

publicstaticLazySingleton2getInstance(){

//如果對象不存在,就new一個新的對象,否則返回已有的對象

if(lazySingleton2==null){

synchronized(LazySingleton2.class){

if(lazySingleton2==null){

lazySingleton2=newLazySingleton2();

returnlazySingleton2;

}

這時還有一個問題,就是在創建一個對象時,在JVM中會經過三步:

(1)為對象分配內存空間

(2)初始化該對象

(3)將該對象指向分配好的內存空間

那么在執行我們這個多線程代碼的過程中,有可能他不按照這三部的順序走,那么就會導致一個指令重排的問題,解決此問題的方法就是加關鍵字volatile

classLazySingleton3{

//構造器私有,堵死了外界利用new創建此類對象的可能

privateLazySingleton3(){

//提供對象,是外界獲取本類對象的唯一全局訪問點

privatevolatilestaticLazySingleton3lazySingleton3;

publicstaticLazySingleton3getInstance(){

//如果對象不存在,就new一個新的對象,否則返回已有的對象

if(lazySingleton3==null){

synchronized(LazySingleton3.class){

if(lazySingleton3==null){

lazySingleton3=newLazySingleton3();

returnlazySingleton3;

}

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

classLazySingleton4{

//提供變量,控制反射

publicstaticbooleans=false;

//構造器私有,堵死了外界利用new創建此類對象的可能

privateLazySingleton4(){

if(s==false){

//當第一個對象成功獲取之后,第二個對象就不能通過反射獲取了

s=true;

}else{

thrownewRuntimeException(不要用反射破壞異常

//提供對象,是外界獲取本類對象的唯一全局訪問點

privatevolatilestaticLazySingleton4lazySingleton4;

publicstaticLazySingleton4getInstance(){

//如果對象不存在,就new一個新的對象,否則返回已有的對象

if(lazySingleton4==null){

synchronized(LazySingleton4.class){

if(lazySingleton4==null){

lazySingleton4=newLazySingleton4();

returnlazySingleton4;

}

volatile,synchronized這兩個關鍵字就能保證線程安全,但是每次訪問時都要同步,會影響性能,且消耗更多的資源,這是懶漢式單例的缺點。

2.2單利模式的實現方式一:餓漢式

該模式的特點是類一旦加載就創建一個單例,保證在調用getInstance方法之前單例已經存在了。

代碼:

publicclassHungrySingleton{

privatestaticfinalHungrySingletoninstance=newHungrySingleton();

privateHung

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論