轉自:https://www.cnblogs.com/lwbqqyumidi/p/3738059.html
在Java設計模式中,單例模式相對來說算是比較簡單的一種構建模式。適用的情境在於:對於定義的一個類,在整個應用程式執行期間只有唯一的一個執行個體對象。如Android中常見的Application對象。
通過單例模式,自行執行個體化並向這個系統提供這個單一執行個體的存取方法。
根據此單一執行個體產生的時機不同(當然,都是指第一次,也是唯一一次產生此單一執行個體時),可以將其分為懶漢式、餓漢式和登記式。
一、懶漢式:
其特點是消極式載入,即當需要用到此單一執行個體的時候,才去初始化此單一執行個體。常見經典的寫法如下:
1 package com.qqyumidi; 2 3 public class SingleTon { 4 5 // 靜態執行個體變數 6 private static SingleTon instance; 7 8 // 私人化建構函式 9 private SingleTon() {10 11 }12 13 // 靜態public方法,向整個應用提供單例擷取方式14 public static SingleTon getInstance() {15 if (instance == null) {16 instance = new SingleTon();17 }18 return instance;19 }20 21 }
懶漢式的安全執行緒寫法
1 package com.qqyumidi; 2 3 public class SingleTon { 4 5 // 靜態執行個體變數加上volatile 6 private static volatile SingleTon instance; 7 8 // 私人化建構函式 9 private SingleTon() {10 11 }12 13 // 雙重檢查鎖14 public static SingleTon getInstance() {15 if (instance == null) {16 synchronized(Singleton.class){17 if(instance == null){18 instance = new SingleTon();19 }20 }21 }22 return instance;23 }24 25 }
二、餓漢式:
餓漢式的特點是應用中尚未需要用到此單一執行個體的時候即先執行個體化。常見的經典寫法為:
1 package com.qqyumidi; 2 3 public class SingleTon { 4 5 // 靜態執行個體變數,直接初始化 6 private static SingleTon instance = new SingleTon(); 7 8 // 私人化建構函式 9 private SingleTon() {10 11 }12 13 // 靜態public方法,向整個應用提供單例擷取方式14 public static SingleTon getInstance() {15 return instance;16 }17 18 }
三、登記式單例模式:
登記式單例模式,一般是通過一個專門的類對各單例模式的此單一執行個體進行管理和維護。通過Map方式可以方便的實現此中目的。常見的代碼如下:
1 package com.qqyumidi; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 public class SingleTonManager { 7 8 private static Map singleTonMap = new HashMap(); 9 10 public static void main(String[] args) {11 // 擷取A類的單例12 A a = (A) getInstance(A.class.getName());13 // 擷取B類的單例14 B b = (B) getInstance(B.class.getName());15 }16 17 // 根據類型擷取單例18 public static Object getInstance(String className) {19 // 判斷singleTonMap中是否有此單例,有則取得後返回,無則添加單例後返回20 if (!singleTonMap.containsKey(className)) {21 try {22 singleTonMap.put(className, Class.forName(className).newInstance());23 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {24 // TODO Auto-generated catch block25 e.printStackTrace();26 }27 }28 return singleTonMap.get(className);29 }30 }31 32