一、什麼是單例模式
單例:確保一個類別僅有一個實例,並提供一個存取它的全域存取點。
單例模式是一種常用的軟體設計模式之一,其目的是確保整個應用中只存在類別的唯一個實例。
例如我們在系統啟動時,需要加載一些公共的配置信息,對整個應用程序的整個生命週期中都可見且唯一,這時需要設計成單例模式。如:spring容器,session工廠,緩存,資料庫連接池等等。
二、如何保證實例的唯一
1)防止外部初始化
5)線程安全 三、幾種單利模式的比較 (1)餓漢式“因為餓,所以要立即吃飯,刻緩的靜態變量進行實例化。
public class Singleton { private static final Singleton singleton = new Singleton(); private Singleton() { } public static Singleton getInstance() { return singleton; } }①聲明靜態私有類別變量,且立即實例化,保證實例化一次②私有構造,防止外部實例化(透過反射是可以實例化的,不考慮此種情況)③提供public的getInstance()方法供外部取得單例實例好處:線程安全;取得實例速度快缺點:類別載入即初始化實例,記憶體浪費 (2)懶漢式「這個人比較懶,等用著你的時候才去實例化”,延遲載入。
public class Singleton { private static Singleton singleton = null; private Singleton() { } public static Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } }優點:在取得實例的方法中,進行實例的初始化,節省系統資源缺點:①如果取得實例時,初始化工作較多,載入速度會變慢,影響系統係能②每次取得實例都要進行非空檢查,系統開銷大③非執行緒安全,當多個執行緒同時存取getInstance()時,可能會產生多個實例 接下來對它進行執行緒安全改造:
1)同步鎖定
public synchronized static Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; }優點:線程安全,缺點:每次獲取實例都要加鎖,耗費資源,其實只要實例已經生成,以後獲取就不需要再鎖了 2)雙重檢查鎖定
public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; }優點:執行緒安全,進行雙重檢查,確保只在實例未初始化前進行同步,效率高缺點:還是實例非空判斷,耗費一定資源 3)靜態內部類
public class Singleton { private Singleton() { } private static class SingletonHolder { private static final Singleton singleton = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.singleton; } }優點避免了同步帶來的效能損耗,又能夠延遲載入 (3)枚舉
public enum Singleton { INSTANCE; public void init() { System.out.println("资源初始化。。。"); } }天然執行緒安全,可防止反射產生實例。 四、單例模式的優缺點