java設計模式-單例模式

模式導讀:數據庫

單例模式:保證一個類只有一個實例,而且可以提供一個訪問該實例的全局訪問點。緩存

優勢:因爲單例模式只生成一個實例,減小了系統性能開銷,當一個對象的產生須要比較多的資源時,如讀取配置,產生其餘依賴對象時,則能夠經過在應用啓動時直接產生一個單例對象,而後永久駐留內存的方式來解決。安全

單例模式能夠在系統設置全局的訪問點,優化環共享資源訪問,例如能夠設計一個單例類,負責全部數據表的映射處理。併發

參考類圖:性能

代碼實現:測試

常見的五種單例模式實現方式:優化

主要:spa

  餓漢式:線程安全,調用效率高,不能延時加載。線程

 1 package com.etc;  2 
 3 //餓漢式單例模式,不可延時加載,調用效率高
 4 public class HungrySingleton {  5     // 類初始化時當即加載這個對象,加載類時自然的是線程安全的
 6     private static HungrySingleton instance = new HungrySingleton();  7 
 8     // 讓構造器爲 private,這樣該類就不會被實例化
 9     private HungrySingleton() { 10  } 11 
12     // 獲取惟一可用的對象,方法沒有同步,調用效率高
13     public static HungrySingleton getInstance() { 14         return instance; 15  } 16 
17     public void showMessage() { 18         System.out.println("餓漢式單例模式測試輸出:當即加載!"); 19  } 20 }

 懶漢式:線程安全,調用效率不高,能夠延時加載。設計

 1 package com.etc;  2 //懶漢式單例模式
 3 public class LazySingleton {  4     //類初始化時,不初始化對象,延時加載
 5     private static LazySingleton instance=null;  6     //私有化構造器
 7     private LazySingleton() {  8         
 9  } 10     //設置了方法同步,每次調用該方法都要同步,併發效率低,資源利用率高
11     public synchronized static LazySingleton getInstance() { 12         //當須要使用時再初始化類對象
13         if(instance==null) { 14             instance=new LazySingleton(); 15  } 16         return instance; 17  } 18     public void showMessage() { 19         System.out.println("懶漢式單例模式測試輸出:延時加載!"); 20  } 21 }

其餘:

 雙重檢測鎖式:因爲JVM底層內部模型緣由,偶爾會出問題,不建議使用。

 1 package com.etc;  2 //雙重檢測鎖式單例模式
 3 public class DCClockSingleton {  4 
 5     public static DCClockSingleton instance=null;  6     //私有化構造器
 7     private DCClockSingleton() {  8 
 9  } 10     //將同步內容下放到if內部,提升了執行的效率,沒必要每次獲取對象都進行同步,只有第一次才同步建立了之後就沒必要同步
11     public static DCClockSingleton getInstance() { 12         if(instance ==null) { 13  DCClockSingleton ds; 14             //第一重檢測鎖
15             synchronized(DCClockSingleton.class) { 16                 ds=instance; 17                 if(ds==null) { 18                     //第二重檢測鎖
19                     synchronized(DCClockSingleton.class) { 20                         if(ds==null) { 21                             ds=new DCClockSingleton(); 22  } 23  } 24                     instance=ds; 25  } 26  } 27  } 28         return instance; 29  } 30     public void showMessage() { 31         System.out.println("雙重檢測鎖單例模式測試輸出:延時加載!"); 32  } 33 }

  靜態內部類式:線程安全,調用效率高,能夠延時加載。

 1 package com.etc;  2 //靜態內部類單例模式
 3 public class StaticNativeClassSingleton {  4     //私有化構造器
 5     private StaticNativeClassSingleton() {  6  }  7     //靜態內部類,實現類的延時加載
 8     private static class InstanceSingleton{  9         private static final StaticNativeClassSingleton instance=new StaticNativeClassSingleton(); 10  } 11     //方法未同步,效率高
12     public static StaticNativeClassSingleton getInstance() { 13         return InstanceSingleton.instance; 14  } 15     public void showMessage() { 16         System.out.println("靜態內部類單例模式測試輸出:延時加載!"); 17         
18  } 19 }

  枚舉單例:線程安全,調用效率高,不能延時加載。

1 package com.etc; 2 //枚舉單例模式
3 public enum EnumSingleton { 4     //枚舉元素自己就是表明單例對象
5  instance; 6     public void showMessage() { 7         System.out.println("枚舉單例模式測試輸出:當即加載!"); 8  } 9 }

ps:測試類

 1 package com.etc;  2 
 3 public class SingletonTest {  4 
 5     public static void main(String[] args) {  6         //餓漢式單例模式測試輸出
 7         HungrySingleton hungry=HungrySingleton.getInstance();  8  hungry.showMessage();  9         //懶漢式單例模式測試輸出
10         LazySingleton lazy=LazySingleton.getInstance(); 11  lazy.showMessage(); 12         //雙重檢測鎖單例模式測試輸出
13         DCClockSingleton dcclock=DCClockSingleton.getInstance(); 14  dcclock.showMessage(); 15         //靜態內部類單例模式測試輸出
16         StaticNativeClassSingleton sns=StaticNativeClassSingleton.getInstance(); 17  sns.showMessage(); 18         //枚舉單例模式測試輸出
19         EnumSingleton e=EnumSingleton.instance; 20  e.showMessage(); 21         
22  } 23 }

效果截圖:

單例模式優缺點:

優勢:

一、在內存裏只有一個實例,減小了內存的開銷,尤爲是頻繁的建立和銷燬實例。
二、避免對資源的多重佔用。

缺點:

沒有接口,不能繼承,與單一職責原則衝突,一個類應該只關心內部邏輯,而不關心外面怎麼樣來實例化。

適用場景:

一、要求生產惟一序列號。二、WEB 中的計數器,不用每次刷新都在數據庫里加一次,用單例先緩存起來。三、建立的一個對象須要消耗的資源過多,好比 I/O 與數據庫的鏈接等。

相關文章
相關標籤/搜索