【設(shè)計(jì)模式】- 單例模式 6種實(shí)現(xiàn)方法

單例模式,是一種常用的軟件設(shè)計(jì)模式。在它的核心結(jié)構(gòu)中只包含一個(gè)被稱為單例的特殊類。通過單例模式可以保證系統(tǒng)中,應(yīng)用該模式的一個(gè)類只有一個(gè)實(shí)例。即一個(gè)類只有一個(gè)對象實(shí)例。

  1. 單例類只能有一個(gè)實(shí)例。
  2. 單例類必須自己創(chuàng)建自己的唯一實(shí)例。
  3. 單例類必須給所有其他對象提供這一實(shí)例。

懶漢式

當(dāng)?shù)谝淮握{(diào)用的時(shí)候才會創(chuàng)建對象,合理占用資源。

/**
 * 懶漢式(線程安全)
 */
public class Singleton01 {

    private static Singleton01 singleton01;

    // 私有構(gòu)造方法
    private Singleton01() {
    }

    // 同步獲取單例對象,保證線程安全
    public static synchronized Singleton01 getInstance() {
        // 單例對象為空的時(shí)候,創(chuàng)建單例對象
        if (singleton01 == null) {
            singleton01 = new Singleton01();
        }
        return singleton01;
    }

}

餓漢式

類加載的時(shí)候就會初始化,他是線程安全的,但是類加載的時(shí)候就會初始化會預(yù)先消耗一部分資源。

/**
 * 餓漢式
 */
public class SingleTon02 {

    private static SingleTon02 singleTon02 = new SingleTon02();

    // 私有構(gòu)造方法
    private SingleTon02() {
    }

    public static SingleTon02 getInstance() {
        return singleTon02;
    }
}

雙檢索式

該方式能保證需要的時(shí)候才初始化單例,還能保證線程安全,而且單例初始化的時(shí)候調(diào)用getInstance()不會進(jìn)行同步鎖。

/**
 * 雙檢索(DCL式).
 */
public class Singleton03 {

    private volatile static Singleton03 singleton03;

    // 私有構(gòu)造方法
    private Singleton03() {
    }

    // 同步該方法獲取單例對象
    public static Singleton03 getInstance() {
        // 但對象為空時(shí)同步這個(gè)方法
        if (singleton03 == null) {
            synchronized (Singleton03.class) {
                // 再判斷是否為空
                if (singleton03 == null) {
                    // 為空的話就創(chuàng)建對象
                    singleton03 = new Singleton03();
                }
            }
        }
        return singleton03;
    }
}

靜態(tài)內(nèi)部類

內(nèi)部類只有在getInstance()方法第一次調(diào)用的時(shí)候才會被加載(實(shí)現(xiàn)了延遲加載效果),而且其加載過程是線程安全的(實(shí)現(xiàn)線程安全)。內(nèi)部類加載的時(shí)候只實(shí)例化了一次instance

/**
 * 靜態(tài)內(nèi)部類,推薦該該方式實(shí)現(xiàn)單例模式.
 */
public class Singleton04 {
    // 私有化構(gòu)造方法
    private Singleton04() {
    }

    /**
     * 靜態(tài)內(nèi)部類.
     * 內(nèi)部類只有在getInstance()方法第一次調(diào)用的時(shí)候才會被加載(實(shí)現(xiàn)了延遲加載效果),
     * 而且其加載過程是線程安全的(實(shí)現(xiàn)線程安全)。內(nèi)部類加載的時(shí)候只實(shí)例化了一次instance
     */
    private static class Singleton05inner {
        public static final Singleton04 INSTANCE = new Singleton04();
    }

    public static Singleton04 getInstance() {
        return Singleton05inner.INSTANCE;
    }
}

枚舉

枚舉是線程安全的,而且任何情況下都是一個(gè)實(shí)例,枚舉不能實(shí)例化,不能被反射。

/**
 * 枚舉.
 */
public enum Singleton05 {
    INSTACNE;

    public static Singleton05 getInstacne() {
        return INSTACNE;
    }
}

容器實(shí)現(xiàn)單例

容器實(shí)現(xiàn)單例,它的好處是可以統(tǒng)一管理單例。

/**
 * 容器實(shí)現(xiàn)單例.
 * 它的好處是可以統(tǒng)一的管理單例,安卓中g(shù)etSystemService(String name)就是用這種方式實(shí)現(xiàn)的.
 */
public class Singleton06 {

    private static Map<String, Object> singletonManagerMap = new HashMap<>();

    // 私有構(gòu)造方法
    private Singleton06() {
    }

    // 注入程序中的單例
    public static void registerSingleton(String key, Object instance) {
        if (!singletonManagerMap.containsKey(key)) {
            singletonManagerMap.put(key, instance);
        }
    }

    // 獲取key值對應(yīng)的單例對象
    public static Object getInstance(String key) {
        return singletonManagerMap.get(key);
    }
}

參考文獻(xiàn) http://www.itdecent.cn/p/8fe210e6aeb9

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容