單例模式(Singleton Pattern):確保某一個類只有一個實例,並且自行實例化並向整個系統提供這個實例,這個類稱爲單例類,它提供全局訪問的方法。單例模式是一種對象建立型模式。git
單例模式有三個要點:一是某個類只能有一個實例;二是它必須自行建立這個實例;三是它必須自行向整個系統提供這個實例。單例模式是結構最簡單的設計模式一,在它的核心結構中只包含一個被稱爲單例類的特殊類。單例模式結構如圖所示:設計模式
public class Singleton { private static Singleton singleton; private Singleton() { } public static Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } }
public class EagerSingleton { private static EagerSingleton eagerSingleton = new EagerSingleton(); private EagerSingleton() { } public static EagerSingleton getInstance() { return eagerSingleton; } }
public class LazySingleton { private static LazySingleton instance = null; private LazySingleton() { } //鎖的範圍過大,性能下降 synchronized public static LazySingleton getInstance() { if (null == instance) { instance = new LazySingleton(); } return instance; } }
上面的懶漢單例使用synchronzed
進行線程鎖,範圍過大,影響性能,可使用雙重檢查鎖定(Double-CheckLocking)來實現懶漢式單例類,代碼以下:安全
class LazySingleton2 { //volatile保證多線程間共享變量的可見性 private volatile static LazySingleton2 instance = null; private LazySingleton2() { } //雙重檢查鎖定(Double-Check Locking) public static LazySingleton2 getInstance() { //第一重判斷 if (null == instance) { //鎖定代碼塊 synchronized (LazySingleton2.class) { //第二重判斷 if (null == instance) { instance = new LazySingleton2(); } } } return instance; } }
餓漢式單例類不能實現延遲加載,無論未來用不用始終佔據內存;懶漢式單例類線程安全控
制煩瑣,並且性能受影響。多線程
還有一種更好的單例實現方式,稱之爲Initialization Demand Holder (IoDH)的技術,既能夠實現延遲加載,又能夠保證線程安全,不影響系統性能.在IoDH中,咱們在單例類中增長一個靜態(static)內部類,在該內部類中建立單例對象,再將該單例對象經過getInstance()方法返回給外部使用,實現代碼以下:函數
class Singleton2 { private Singleton2() { } private static class HolderClass { private final static Singleton2 instance = new Singleton2(); } public static Singleton2 getInstance() { return HolderClass.instance; } }
單例模式可確保只有一個實例對象,其提供了實例的全局訪問點來得到該實例,爲了不多線程訪問的隱患,可以使用餓漢單例模式和IoDH技術的懶漢單例模式。性能