單例模式

定義:確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。

單例模式的七種實(shí)現(xiàn)方式:

1.餓漢式

public class SingleInstance {

    private static SingleInstance mInstance = new SingleInstance();
    
    private SingleInstance() {}
    
    public static SingleInstance getInstance() {
        return mInstance;
    }
}

2.懶漢式--線程不安全

public class SingleInstance {

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

3.懶漢式--線程安全

public class SingleInstance {

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

優(yōu)點(diǎn):懶漢式的優(yōu)點(diǎn)是只有在使用時(shí)才會(huì)被實(shí)例化,在一定程度上節(jié)約了資源;
缺點(diǎn):每次調(diào)用getInstance()都要同步,造成不必要的同步開(kāi)銷;

4.Double Check Lock(DCL)雙重校驗(yàn)鎖,線程安全

public class SingleInstance {

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

getInstance()方法中對(duì)mInstance進(jìn)行了兩次判空:
第一層判斷主要是為了避免不必要的同步;
第二層判斷是為了在null的情況下創(chuàng)建實(shí)例;
優(yōu)點(diǎn):資源利用率高,第一次執(zhí)行getInstance()的單例對(duì)象才會(huì)被實(shí)例化,效率高;
缺點(diǎn):第一次加載反應(yīng)稍慢,由于Java內(nèi)存模型的原因偶爾會(huì)失敗。在高并發(fā)環(huán)境下也有一定的缺陷,雖然發(fā)生的概率很??;

5.使用靜態(tài)內(nèi)部類的方式

public class SingleInstance {

    private SingleInstance() {}
    
    /**
     * 靜態(tài)內(nèi)部類
     */
    private static class SingleInstanceHolder {
        private static SingleInstance mInstance = new SingleInstance();
    }
    
    public static SingleInstance getInstance() {
        return SingleInstanceHolder.mInstance;
    }
}

當(dāng)?shù)谝淮渭虞dSingleInstance類時(shí)不會(huì)初始化mInstance,只有在第一次調(diào)用SingleInstancegetInstance()方法時(shí)才會(huì)導(dǎo)致mInstance被初始化。因此,第一次調(diào)用getInstance()方法會(huì)導(dǎo)致虛擬機(jī)加載SingleInstanceHolder類,這種方式不僅能保證線程安全,也能夠保證單例對(duì)象的唯一性,同時(shí)也延遲了單例的實(shí)例化。

6.枚舉單例

public enum SingleEnum {
    
    INSTANCE;
    
    public void doSomething() {
        System.out.println("do somth");
    }
}

在上述幾種單例的實(shí)現(xiàn)方式中,如果將對(duì)象實(shí)例進(jìn)行序列化,就會(huì)出現(xiàn)重新創(chuàng)建對(duì)象實(shí)例的情況。而對(duì)應(yīng)枚舉不會(huì)存在這個(gè)問(wèn)題,因?yàn)榧词狗葱蛄谢膊粫?huì)重新生成新的實(shí)例。

7.使用容器實(shí)現(xiàn)單例模式

public class SingleManager {

    private static Map<String, Object> objMap = new HashMap<>();
    
    private SingleManager() {}
    
    public static void registerService(String key, Object instance) {
        if (!objMap.containsKey(instance)) {
            objMap.put(key, instance);
        }
    }
    
    public static Object getService(String key) {
        return objMap.get(key);
    }
}

在程序的初始,將多種單例類型注入到一個(gè)統(tǒng)一的管理類中,在使用是根據(jù)key獲取對(duì)象對(duì)應(yīng)的類型的對(duì)象。這中方式使得我們可以管理多種類型的單例,并且在使用時(shí)可以通過(guò)統(tǒng)一的接口進(jìn)行獲取操作,降低了用戶的使用成本,也對(duì)用戶隱藏了具體的實(shí)現(xiàn),降低耦合度。

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

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

  • 單例模式(SingletonPattern)一般被認(rèn)為是最簡(jiǎn)單、最易理解的設(shè)計(jì)模式,也因?yàn)樗暮?jiǎn)潔易懂,是項(xiàng)目中最...
    成熱了閱讀 4,546評(píng)論 4 34
  • 1 場(chǎng)景問(wèn)題# 1.1 讀取配置文件的內(nèi)容## 考慮這樣一個(gè)應(yīng)用,讀取配置文件的內(nèi)容。 很多應(yīng)用項(xiàng)目,都有與應(yīng)用相...
    七寸知架構(gòu)閱讀 6,978評(píng)論 12 68
  • 1 單例模式的動(dòng)機(jī) 對(duì)于一個(gè)軟件系統(tǒng)的某些類而言,我們無(wú)須創(chuàng)建多個(gè)實(shí)例。舉個(gè)大家都熟知的例子——Windows任務(wù)...
    justCode_閱讀 1,560評(píng)論 2 9
  • 前言 本文主要參考 那些年,我們一起寫(xiě)過(guò)的“單例模式”。 何為單例模式? 顧名思義,單例模式就是保證一個(gè)類僅有一個(gè)...
    tandeneck閱讀 2,632評(píng)論 1 8
  • 這么晚才上傳我的簡(jiǎn)書(shū),是小有原因的,因?yàn)榻裉熳钪匾氖虑榫褪前央娔X更換及資料的轉(zhuǎn)移,所以到了現(xiàn)在才有時(shí)間來(lái)寫(xiě)我的簡(jiǎn)...
    AD_Chen閱讀 507評(píng)論 0 5

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