天天看點

Android 單例模式幾種寫法及優缺點

總結一波單例設計模式的幾種寫法以及各自存在的優缺點。

1,餓漢式

顧名思義,執行個體對象早早的就建立出來了。這種方式在類加載的時候就完成了初始化,是以類加載過程比較緩慢,但是在使用過程中擷取執行個體對象的速度比較快,也因為這種方式是基于類加載機制的,是以避免了多線程的同步問題。

public class SingleTon {

    private static SingleTon instance = new SingleTon();
    private SingleTon(){}

    public static  SingleTon getInstance(){
        return instance;
    }

}
           

優點:擷取對象的速度快;避免了多線程的同步問題

缺點:類加載過程慢

2,懶漢式(線程不安全)

顧名思義,執行個體對象建立時間較晚。執行個體對象在使用者第一次調用的時候初始化,雖然節約了資源,但是第一次加載時反應稍慢,而且在多線程的情況下不能正常使用。

public class SingleTon {

    private static SingleTon instance;

    private SingleTon() {}

    public static SingleTon getInstance() {
        if (instance == null) {
            instance = new SingleTon();
        }

        return instance;
    }
}
           

優點:節約資源

缺點:第一次加載時需要執行個體化,反應稍慢;多線程下不能正常工作

3,懶漢式(線程安全)

這種寫法時線程安全的,在多線程情況下是可以正常工作的,但是每次擷取執行個體對象的時候都需要進行同步,造成不必要的同步開銷。在移動應用開發端用到同步的情況很少,是以不建議使用。

public class SingleTon {

    private static SingleTon instance;

    private SingleTon() {}

    public static synchronized SingleTon getInstance() {
        if (instance == null) {
            instance = new SingleTon();
        }

        return instance;
    }
}
           

優點:在多線程下可以安全的使用

缺點:造成不必要的同步開銷

4,雙重檢查機制(DCL)

這種寫法有兩次判空。第一次判空是減少不必要的同步開銷,也是對上面寫法的改進;第二次判空是建立執行個體對象。注意這裡使用了volatile關鍵字

public class SingleTon {

    private static volatile SingleTon instance;

    private SingleTon() {}

    public static SingleTon getInstance() {
        if (instance == null) {
            synchronized (SingleTon.class) {
                if (instance == null) {
                    instance = new SingleTon();
                }

            }
        }

        return instance;
    }
}
           

優點:資源使用率高,線程安全

缺點:第一次加載時反應稍慢,在高并發環境下有缺陷

5,靜态内部類

這種單例模式在第一次類加載時并不會初始化,隻有在第一次調用getInstance();時虛拟機加載SingletonHolder并初始化SingleTon執行個體,也是線程安全的,也是推薦使用的。

public class SingleTon {

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

    private static class SingletonHolder{
        private static final SingleTon instance = new SingleTon();
    }

}
           

優點:線程安全,節約資源

缺點:第一次加載時反應稍慢

繼續閱讀