《設計模式》之(一)單例模式 - 創建型

生活就要奮鬥

單例模式,按目的來分屬於創建型模式。是指一個類只有一個實例,該實例對象必須由該單例類自行創建。其特點:1.構造器私有化;2.只有一個實例對象;3.由單例類自行創建;4.對外提供一個全局的訪問方法。目的爲了節省內存資源、保證數據內容的一致性。直接看代碼,代碼中註釋,簡便易懂,如下:

<一>懶漢式單例模式:

/**
 * 懶漢式單例:類加載時不生成實例對象,第一次去調用getInstance()方方法時,纔去創建實例對象。
 */
public class LazySingleton {

    /* 實例對象 */
    private static LazySingleton instance;

    /* 構造器私有 */
    private LazySingleton() {
    }

    /* 對外提供獲取單例實例的全局訪問方法 */
    public static void getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
    }

    // 以下是懶漢式單例模式的變種:保證線程安全,但每次訪問都要同步,影響性能,消耗更多的資源。
    private static volatile LazySingleton instanceVariant;

    public static synchronized void getInstanceVariant() {
        if (instance == null) {
            instance = new LazySingleton();
        }
    }
}

<二>餓漢式單例模式:

/**
 * 餓漢式單例:類一旦加載就初始化實例,是線程安全的;
 * 但容易產生垃圾(當沒有調用這個實例時,由於該單例在類創建的同時就初始化了一個靜態的對象,所以容易造成內存空間的浪費)
 */
public class HungrySingleton {
    /* 實例對象 */
    private static final HungrySingleton instance = new HungrySingleton();

    /* 構造器私有 */
    private HungrySingleton() {
    }

    /* 供外部調用的方法 */
    public static HungrySingleton getInstance() {
        return instance;
    }
}

<三>雙重校驗鎖單例模式:

/**
 * 雙重校驗鎖單利:線程安全,延遲初始化
 */
public class DoubleLockSingleton {

    /* volatile關鍵字能夠禁止指令重排,保證在寫操作沒有完成之前不能調用讀操作 */
    private static volatile DoubleLockSingleton instance;

    /* 構造器私有化 */
    private DoubleLockSingleton() {
    }

    /* 雙重檢驗:第一次避免進入鎖,減少性能開銷;第二次進行同步,避免多線程問題,防止生成多個對象;
     * 由於JVM中創建對象可能導致重排序,在多線程訪問下會存在問題,使用volatile修飾變量,禁止指令重排,有效解決這個問題 */
    private static DoubleLockSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleLockSingleton.class) {
                if (instance == null) {
                    instance = new DoubleLockSingleton();
                }
            }
        }
        return instance;
    }
}

<四>靜態內部類單例模式:

/**
 * 靜態內部類單例:充分利用了靜態內部類的特點。只有第一次調用getInstance()方法時,
 * JVM才加載內部類實例化instance對象,只有一個線程可以獲取對象的初始化鎖,保證單例對象唯一,是線 
 * 程安全的。這也是目前比較推薦的方式。
 */
public class StaticInnerSingleton {

    /* 構造器私有 */
    private StaticInnerSingleton() {
    }

    /* 靜態內部類:在此創建單例對象 */
    private static class SingletonInstance {
        private static final StaticInnerSingleton instance = new StaticInnerSingleton();
    }

    /* 對外提供獲取單例實例的全局訪問方法 */
    public static StaticInnerSingleton getInstance() {
        return SingletonInstance.instance;
    }
}

<五>枚舉單例模式:

/**
 * 枚舉單例:是線程安全的。充分利用了枚舉的特性,簡單且高效。
 * 實際開發中枚舉單例模式還是用到的比較少
 */
public enum EnumerateSingleton {

    INSTANCE;

    /* 可以省略此方法,通過Singleton.INSTANCE進行操作*/
    public static EnumerateSingleton getInstance() {
        return EnumerateSingleton.INSTANCE;
    }

}

注:歡迎指教!

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