精講Android設計模式-單例模式


原文鏈接

更多教程


爲什麼要使用單例模式

單例的優點

1.只有一個實例,節省開銷
2.全局使用方便,同時避免頻繁創建和銷燬

使用單例的注意點:
要避免造成 內存泄漏

常用的單例模式

單例不僅要滿足線程安全,還要注意防止序列化產生新對象。如果單例實現了Serializable接口,就必須加入如下方法(枚舉單例不用這麼做,因爲JVM能保障這點):

private Object readResolve()  throws ObjectStreamException{
    return INSTANCE;
}

原文鏈接

更多教程


餓漢式

餓漢式:就是在類初始化時就實例化,所以是線程安全的。
缺點是:
1.沒有懶加載,在不需要的時候也會被實例化,造成內存浪費。
2.實例化方法對外部調用不友好,傳參不方便

public class Singleton implements Serializable {
    private static final Singleton INSTANCE = new Singleton();
    // 私有化構造函數
    private Singleton(){}

    public static Singleton getInstance(){
        return INSTANCE;
    }

    /**
     * 如果實現了Serializable, 必須重寫這個方法
     */
    private Object readResolve() throws ObjectStreamException {
        return INSTANCE;
    }
}

懶漢式

延遲加載(使用時加載),節省內存
雙重判空,第一次判空防止重複加鎖,第二次判空才實例化
防止DCL指令重拍序,加volatile關鍵字

public class Singleton {
    private volatile static Singleton INSTANCE; //聲明成 volatile
    private Singleton (){}

    public static Singleton getSingleton() {
        if (INSTANCE == null) {                         
            synchronized (Singleton.class) {
                if (INSTANCE == null) {       
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }

}

//如果實現了Serializable, 必須重寫同上面餓漢式一樣的readResolve方法

枚舉式

由JVM保證線程安全
序列化和反射攻擊已經被枚舉解決

//enum枚舉類
public enum Singleton { 
    INSTANCE;  
    public void yourMethod() {  

    }  
}

內部類實現單例

當Singleton被加載時,其內部類並不會被初始化,故可以確保當 Singleton類被載入JVM時,不會初始化單例類。只有 getInstance() 方法調用時,纔會初始化 instance。同時,由於實例的建立是時在類加載時完成,故天生對多線程友好,getInstance() 方法也無需使用同步關鍵字。

public class Singleton { 
    /** 
     * 類級的內部類,也就是靜態的成員式內部類,該內部類的實例與外部類的實例沒有綁定關係, 
     * 而且只有被調用到纔會裝載,從而實現了延遲加載 
     */ 
    private static class SingletonHolder{ 
        /** 
         * 靜態初始化器,由JVM來保證線程安全 
         */ 
        private static final Singleton instance = new Singleton(); 
    } 
    /** 
     * 私有化構造方法 
     */ 
    private Singleton(){ 
    } 

    public static  Singleton getInstance(){ 
        return SingletonHolder.instance; 
    } 
}

原文鏈接

更多教程


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章