1. 程式人生 > >單例模式使用總結

單例模式使用總結

前言

記錄單例模式的多種使用方式,以及自己的理解

餓漢模式

public class HungrySingleMode {

    private static HungrySingleMode mInstance=new HungrySingleMode();

    private HungrySingleMode(){}

    public static HungrySingleMode getInstance(){
        return mInstance;
    }
}

個人理解

類載入的時候把靜態的變數已經載入到記憶體裡了,使用的時候直接獲取不用再建立例項物件,執行時稍微快一些。如果沒有被使用,則有點浪費記憶體。因為在類載入的時候已經建立了唯一的例項,所以在多執行緒執行的時候不會出現同步的問題。

懶漢模式(執行緒不安全)

public class LazySingleMode {

    private static LazySingleMode mInstance=null;

    private LazySingleMode(){}

    public static LazySingleMode getInstance(){
        if(mInstance==null){
            mInstance=new LazySingleMode();
        }
        return mInstance;
    }
}

個人理解

在第一次呼叫的時候才會建立例項,這就導致執行的時候會稍微慢一些,但是又保證了不會浪費記憶體。在同步方面如果兩個執行緒同時呼叫這個方法,由於沒有同步鎖的控制,會導致建立多個例項,會出現同步問題。

懶漢模式(執行緒安全)

public class LazySingleSafeMode {
    private static LazySingleSafeMode mInstance;

    private LazySingleSafeMode(){}

    public static synchronized LazySingleSafeMode getInstance(){
        if
(mInstance==null){ mInstance=new LazySingleSafeMode(); } return mInstance; } }

個人理解

在呼叫的方法上加上同步鎖解決同步問題,但是每次呼叫都要去判斷同步的問題,增加了開銷。

雙重檢查模式(DCL)

public class DLCSingleMode {
    private volatile static DLCSingleMode mInstance;

    private DLCSingleMode(){}

    public static DLCSingleMode getInstance(){
        if (mInstance==null){
            synchronized (DLCSingleMode.class){
                if(mInstance==null){
                    mInstance=new DLCSingleMode();
                }
            }
        }
        return mInstance;
    }
}

個人理解

首先,靜態變數用volatitle關鍵字申明,保證了原子性(有待深入理解)。
其次,在呼叫方法裡面進行了兩次判空,第二次判空進行程式碼塊的同步鎖定,保證同步問題。第一次判空可以避免多次同步的呼叫,既保證同步也避免了多餘的同步開銷浪費。
最後,在某些情況下也會存在失效的問題,具體情況待深入理解。

靜態內部類

public class StaticInnerSingleMode {

    private StaticInnerSingleMode(){}

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

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

個人理解

在類載入的時候,不會初始化instance例項,只有在第一次呼叫的時候才會建立例項,同時也能保證執行緒安全。

列舉單例

public enum  EnumSingleMode {
    INSTANCE;

    public void  doSomeThing(){}
}

個人理解

預設列舉例項的建立時執行緒安全的,並且在任何情況下都是單列。–《Android 進階之光》 劉望舒

總結

經過看書學習使用對單例模式有更深刻的認識,當然還有一些不理解之處,需要繼續研究。