1. 程式人生 > >JAVA單例模式(用於表示 執行緒池、資料庫連線池、列印池等系統唯一性資源)

JAVA單例模式(用於表示 執行緒池、資料庫連線池、列印池等系統唯一性資源)

什麼是單例類?1、單例類只能有一個例項。  2、單例類必須自己建立自己的唯一例項。  3、單例類必須給所有其他物件提供這一例項。

單例類的應用場景?

  單例模式確保某個類只有一個例項,而且自行例項化並向整個系統提供這個例項。在計算機系統中,執行緒池、快取、日誌物件、對話方塊、印表機、顯示卡的驅動程式物件常被設計成單例。這些應用都或多或少具有資源管理器的功能。每臺計算機可以有若干個印表機,但只能有一個Printer Spooler,以避免兩個列印作業同時輸出到印表機中。每臺計算機可以有若干通訊埠,系統應當集中管理這些通訊埠,以避免一個通訊埠同時被兩個請求同時呼叫。總之,選擇單例模式就是為了避免不一致狀態,避免政出多頭。

兩種單例模式:懶漢式和餓漢式。懶漢式要注意執行緒安全問題。

一、懶漢式單例

  1. //懶漢式單例類.在第一次呼叫的時候例項化自己 
  2. publicclass Singleton {  
  3.     private Singleton() {}  
  4.     privatestatic Singleton single=null;  
  5.     //靜態工廠方法 
  6.     publicstatic Singleton getInstance() {  
  7.          if (single == null) {    
  8.              single = new Singleton();  
  9.          }    
  10.         return single;  
  11.     }  
  12. }  
Singleton通過將構造方法限定為private避免了類在外部被例項化,在同一個虛擬機器範圍內,Singleton的唯一例項只能通過getInstance()方法訪問。

(事實上,通過Java反射機制是能夠例項化構造方法為private的類的,那基本上會使所有的Java單例實現失效。此問題在此處不做討論,姑且掩耳盜鈴地認為反射機制不存在。)

但是以上懶漢式單例的實現沒有考慮執行緒安全問題,它是執行緒不安全的,併發環境下很可能出現多個Singleton例項,要實現執行緒安全,有以下三種方式,都是對getInstance這個方法改造,保證了懶漢式單例的執行緒安全,如果你第一次接觸單例模式,對執行緒安全不是很瞭解,可以先跳過下面這三小條,去看餓漢式單例,等看完後面再回頭考慮執行緒安全的問題:

1、在getInstance方法上加同步

  1. publicstaticsynchronized Singleton getInstance() {  
  2.          if (single == null) {    
  3.              single = new Singleton();  
  4.          }    
  5.         return single;  
  6. }  

2、雙重檢查鎖定

  1. publicstatic Singleton getInstance() {  
  2.         if (singleton == null) {    
  3.             synchronized (Singleton.class) {    
  4.                if (singleton == null) {    
  5.                   singleton = new Singleton();   
  6.                }    
  7.             }    
  8.         }    
  9.         return singleton;   
  10.     }  

3、靜態內部類

  1. publicclass Singleton {    
  2.     privatestaticclass LazyHolder {    
  3.        privatestaticfinal Singleton INSTANCE = new Singleton();    
  4.     }    
  5.     private Singleton (){}    
  6.     publicstaticfinal Singleton getInstance() {    
  7.        return LazyHolder.INSTANCE;    
  8.     }    
  9. }    
這種比上面1、2都好一些,既實現了執行緒安全,又避免了同步帶來的效能影響。

二、餓漢式單例

  1. //餓漢式單例類.在類初始化時,已經自行例項化 
  2. publicclass Singleton1 {  
  3.     private Singleton1() {}  
  4.     privatestaticfinal Singleton1 single = new Singleton1();  
  5.     //靜態工廠方法 
  6.     publicstatic Singleton1 getInstance() {  
  7.         return single;  
  8.     }  
  9. }  
餓漢式在類建立的同時就已經建立好一個靜態的物件供系統使用,以後不再改變,所以天生是執行緒安全的。