標籤:singleton 單例模式
單例模式:在上下文中只有一個對象的執行個體。
應用情境:線程池,緩衝等一個系統只需要一個的情境。
三種常見單例模式:
1. 消極式載入
public class Singleton { private static Singleton uniqueInstance; private Singleton() {} public static Singleton getInstance() { if (uniqueInstance == null) uniqueInstance = new Singleton(); return uniqueInstance; }}
使用時通過調用類的靜態方法來擷取:
Singleton singleton =Singleton.getInstance();
存在問題:多線程同步問題
多線程在第一次產生對象時,存在同時執行 if (uniqueInstance == null) 判斷的可能,從而同時多次 new執行個體
改進:
public class SynSingleton { private static SynSingleton uniqueInstance; private SynSingleton() {} public static synchronized SynSingleton getInstance() { if (uniqueInstance == null) uniqueInstance = new SynSingleton(); return uniqueInstance; }}
如此通過synchronized代碼塊的方式,實現同步。
2. 急切執行個體化
上述方式每次在擷取對象時,都要做同步synchronized操作,開銷較大,而同步操作僅在第一次new時有效(隨後每次調用均不做new操作,相當於唯讀不寫),因此可以在類載入時就new對象,隨後則不在做new操作,改進如下:
public class UrgSingleton { private static UrgSingleton uniqueInstance = new UrgSingleton(); private UrgSingleton() {} public static UrgSingleton getInstance() { return uniqueInstance; }}
延遲執行個體化與急切執行個體化的優缺點也較明顯:
如果此對象開銷較大,而整個過程又沒有利用,則急切執行個體化出來的對象,白白消耗了資源。
而延時執行個體化同步問題,存在開銷較大的情況,於是有了 下面的雙重檢查加鎖方式。
3. 雙重檢查加鎖
public class DoubleSynSingleton { private static volatile DouleSynSingleton uniqueInstance; private DoubleSynSingleton() {} public static DoubleSynSingleton getInstance() { if (uniqueInstance == null) { synchronized(DoubleSynSingleton.class) { if(uniqueInstance == null) uniqueInstance = new DoubleSynSingleton(); } } return uniqueInstance; }}
如上所示,僅當第一次new對象時,使用synchronized方法,隨後擷取對象執行個體時都在外層的 if (uniqueInstance == null) 判斷後完成退出,不要隨後的同步代碼塊。如此,效能得到提升。
java中單例模式singleton