android設(shè)計模式之單例模式

單例模式介紹

單例模式是使用最廣泛的一種設(shè)計模式刑巧,在這種設(shè)計模式中,單例對象的類必須保證有且只有一種實力存在逆皮。在我們的應(yīng)用中往往會存在這么一個全局對象宅粥,用來統(tǒng)一處理某種行為,如網(wǎng)絡(luò)請求电谣、數(shù)據(jù)緩存秽梅、圖片加載等。像這種情況就沒必要每次使用時都構(gòu)造實例剿牺,而往往采用單例模式

應(yīng)用場景

某種類型的對象有且只有一個對象企垦,避免產(chǎn)生多個對象消耗更多的資源。

實現(xiàn)單例模式有如下關(guān)鍵點:

  1. 構(gòu)造函數(shù)不對外開放晒来,一般都是私有的钞诡。
  2. 對外提供一個靜態(tài)的公共方法或枚舉返回單例對象。
  3. 確保單例對象有且只有一個湃崩,如多線程情況下荧降。
  4. 確保單例對象在反序列化時不會重新創(chuàng)建對象。

單例模式的實現(xiàn)方式

餓漢模式:這是最常見也是最簡單的是想方式攒读,在調(diào)用getInstance前朵诫,在聲明靜態(tài)對象時就進(jìn)行了初始化。

public class Singleton {
    private static Singleton instance=new Singleton();
    
    private Singleton(){ }
    public static Singleton getInstance(){
        
        return instance;
    }
}

懶漢模式:相對于餓漢不同的是薄扁,在用戶第一次調(diào)用getInstance時才進(jìn)行初始化剪返,實現(xiàn)方式如下

public class Singleton {
    private static Singleton instance=new Singleton();
    
    private Singleton(){ }
    public synchronized static Singleton getInstance(){
        if(instance==null) {
            instance=new Singleton();   
        }

        return instance;
    }
}

通過觀察在getInstance方式中添加了synchronized關(guān)鍵字废累,也就是說getInstance是個同步方法,保證在多線程情況下保證了單例的唯一性脱盲。但是這里有個問題——即便instance已經(jīng)初始化了邑滨,每次調(diào)用getInstance方法還是要進(jìn)行同步,而方法同步都會消耗資源宾毒,造成不必要的開銷驼修。這也是懶漢單例模式存在的一個最大問題。

Double check Lock(雙重校驗):這種方式是在懶漢诈铛、餓漢式的基礎(chǔ)的升級,既能夠在需要時才初始化墨礁,又能保證線程安全幢竹,而且單例對象初始化后不需要進(jìn)行同步鎖。

public class Singleton {
    private volatile static Singleton instance = null;
    
    private Singleton(){ }
    public static Singleton getInstance(){
        if(instance==null) {
            synchronized (Singleton.class){
                if(instance==null) {
                    instance=new Singleton();
                }
            }
        }
        return instance;
    }
}

DCL的特點在getInstance方法中的兩次判空:
第一次判斷主要是避免不必要的同步鎖恩静;
第二次判斷是在null情況下創(chuàng)建實例焕毫;
在 instance=new Singleton();這條語句里,大致做了三件事:

  1. 給Singleton的實例分配內(nèi)存
  2. 調(diào)用Singleton的構(gòu)造函數(shù)
  3. 將instance對象指向分配的內(nèi)存空間
    如果按照正常的1驶乾、2邑飒、3步驟順利執(zhí)行,那我們能順利獲得實例對象级乐。但是 編譯器為了優(yōu)化程序指令加快cpu處理速度疙咸,會有指令重排序——也就是說上面的三步可能會1、3风科、2順序撒轮。如果線程A執(zhí)行到3完畢、2未完成之前贼穆。被切換到線程B题山,這個時候instance因為在線程A內(nèi)已經(jīng)執(zhí)行了3,這個實際instance則不會為空故痊。所以線程B直接獲取instance顶瞳,在使用的時候就會報錯。
    這時只需將instance的定義改為private volatile static Singleton instance = null;就可以保證instance對象每次都要從主內(nèi)存中獲取愕秫。

靜態(tài)內(nèi)部類單例模式
當(dāng)?shù)谝淮渭虞dSingleton類時并不會初始化instance慨菱,只有在第一次調(diào)用Singleton的getInstance方法才會導(dǎo)致instance被初始化。因此第一次調(diào)用getInstance方法會導(dǎo)致虛擬機(jī)加載SingletonHolderl類豫领,同時保證了延遲加載抡柿、線程安全、對象的唯一性等恐,所以推薦使用這種方式實現(xiàn)單例模式洲劣。

public class Singleton {
    private Singleton(){ }
    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }
    private static  class SingletonHolder{
        private static final  Singleton instance=new Singleton();

    }
}

枚舉單例

public enum SingletonEnum {
    INSTANCE;
    public void doSomeThing(){
        System.out.println("do sth");
    }

}

容器單例模式

public class SingletonManager {
    private static Map<String,Object> objectMap= new HashMap<>();
    private SingletonManager(){}
    public static  void registerService(String key,Object instance){
        objectMap.put(key,instance);
    }
    public static Object getService(String key){
        return objectMap.get(key);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末备蚓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子囱稽,更是在濱河造成了極大的恐慌郊尝,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件战惊,死亡現(xiàn)場離奇詭異流昏,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)吞获,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門况凉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人各拷,你說我怎么就攤上這事刁绒。” “怎么了烤黍?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵知市,是天一觀的道長。 經(jīng)常有香客問我速蕊,道長嫂丙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任规哲,我火速辦了婚禮跟啤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘媳叨。我一直安慰自己腥光,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布糊秆。 她就那樣靜靜地躺著武福,像睡著了一般。 火紅的嫁衣襯著肌膚如雪痘番。 梳的紋絲不亂的頭發(fā)上捉片,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機(jī)與錄音汞舱,去河邊找鬼伍纫。 笑死,一個胖子當(dāng)著我的面吹牛昂芜,可吹牛的內(nèi)容都是我干的莹规。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼泌神,長吁一口氣:“原來是場噩夢啊……” “哼良漱!你這毒婦竟也來了舞虱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤母市,失蹤者是張志新(化名)和其女友劉穎矾兜,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體患久,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡椅寺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蒋失。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片返帕。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖高镐,靈堂內(nèi)的尸體忽然破棺而出溉旋,到底是詐尸還是另有隱情,我是刑警寧澤嫉髓,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站邑闲,受9級特大地震影響算行,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苫耸,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一州邢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧褪子,春花似錦量淌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至笼痛,卻和暖如春裙秋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缨伊。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工摘刑, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刻坊。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓枷恕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谭胚。 傳聞我的和親對象是個殘疾皇子徐块,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容