設(shè)計(jì)模式-單例模式

1.單例模式的概念

單例模式其實(shí)是一個(gè)類(lèi)只有一個(gè)實(shí)例侦铜,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例的設(shè)計(jì)模式。是最簡(jiǎn)單也是應(yīng)用最廣的設(shè)計(jì)模式函卒。一般用于避免產(chǎn)生多個(gè)對(duì)象消耗系統(tǒng)資源或者要求某種類(lèi)型的對(duì)象必須獨(dú)一無(wú)二的場(chǎng)景辆憔。

2.單例模式常見(jiàn)寫(xiě)法

單例模式有很多種寫(xiě)法,懶漢式报嵌、餓漢式虱咧、雙重校驗(yàn)鎖(DCL)、類(lèi)級(jí)內(nèi)部沪蓬、枚舉等等彤钟,這里我們只講上面說(shuō)的的這5種。

2.1 懶漢式

體現(xiàn)的編程思想

1.懶加載
2.緩存思想

public class LazySingleton {
   //定義一個(gè)變量類(lèi)存儲(chǔ)創(chuàng)建好的實(shí)例對(duì)象 默認(rèn)為空
    private static LazySingleton singleton = null;
    //私有構(gòu)造函數(shù) 避免外部創(chuàng)建
    private LazySingleton(){
    }
    //提供一個(gè)類(lèi)的靜態(tài)方法返回單例對(duì)象 全局可訪問(wèn)
    public static LazySingleton getInstance(){
        //懶體現(xiàn)在第一次需要用到這個(gè)對(duì)象的時(shí)候才會(huì)去創(chuàng)建 以后不會(huì)重新初始化對(duì)象
        if (singleton==null) {
            singleton = new LazySingleton();
        }
        return singleton;
    }
}

2.2 餓漢式

static修飾符的特點(diǎn)
1.static修飾的變量在類(lèi)裝載的時(shí)候初始化
2.多個(gè)實(shí)例的static變量會(huì)共享那個(gè)同一塊內(nèi)存

餓漢式是線程安全的跷叉,因?yàn)樘摂M機(jī)的類(lèi)加載機(jī)制

public class HungerSingleton {
    //類(lèi)加載的時(shí)候創(chuàng)建實(shí)例
    private static HungerSingleton singleton = new HungerSingleton();
    private HungerSingleton(){
    }
    public static HungerSingleton getInstance(){
        //ClassLoader機(jī)制保證了實(shí)例只有一個(gè)
        return singleton;
    }
}

2.3 DCL雙重校驗(yàn)鎖

懶漢式是線程不安全的:比如兩個(gè)線程同時(shí)訪問(wèn)懶漢單例逸雹,在A線程的單例沒(méi)有創(chuàng)建完成的時(shí)候同時(shí)進(jìn)入了防空判斷,單例控制就會(huì)失效云挟。

public class DCLSycSingleton {
    //volatile修飾的變量不會(huì)被本地線程保存
    private volatile static DCLSycSingleton singleton = null;
    private DCLSycSingleton(){
    }
    public static DCLSycSingleton getInstance(){
        //判斷是否為空 否則進(jìn)入代碼塊
        if (singleton==null) {
            //同步塊 線程安全的創(chuàng)建實(shí)例 只允許一次線程操作
            synchronized (DCLSycSingleton.class){
                //再次檢查是否為空
                if (singleton==null) {
                    singleton = new DCLSycSingleton();
                }
            }
        }
        return singleton;
    }
}

2.4 類(lèi)級(jí)內(nèi)部類(lèi)

多線程開(kāi)發(fā)的同步控制:
1.synchronized同步鎖梆砸,這個(gè)比較常見(jiàn)
2.由靜態(tài)初始化器(靜態(tài)字段或static{}代碼塊的初始化器)初
始化數(shù)據(jù)時(shí)
3.訪問(wèn)final字段時(shí)
4.在創(chuàng)建線程之前創(chuàng)建對(duì)象時(shí)
5.線程可以看見(jiàn)它將要處理的對(duì)象時(shí)

  • 思路:
    類(lèi)級(jí)內(nèi)部類(lèi)和多線程缺省同步鎖,靜態(tài)初始化器由虛擬機(jī)保證線程安全园欣,由類(lèi)級(jí)內(nèi)部?jī)?nèi)的方式創(chuàng)建實(shí)例帖世,不調(diào)用到這個(gè)類(lèi)級(jí)內(nèi)部類(lèi)就不會(huì)創(chuàng)建實(shí)例,這樣就保證了懶加載和線程安全
/**
 * 類(lèi)級(jí)內(nèi)部類(lèi) 該類(lèi)的實(shí)例與外部類(lèi)的實(shí)例沒(méi)有依賴 而且只有在被調(diào)用的時(shí)候才會(huì)被裝載沸枯,從而實(shí)現(xiàn)懶加載
 */
    private static class Singleton{
        //靜態(tài)初始化器 由虛擬機(jī)保證線程安全
        private static HolderSingleton singleton = new HolderSingleton();
    }
    private HolderSingleton(){
    }
    public static HolderSingleton getInstance(){
        return Singleton.singleton;
    }

2.5 枚舉

枚舉元素就是一個(gè)單例日矫,由虛擬機(jī)提供序列化機(jī)制,是最好的單例寫(xiě)法绑榴。

public enum EnumSingleton{
    INSTANCE;
    public void doSomethings(){
        //...做一些功能或者其它
    } 
} 

3.單例模式在Android中的運(yùn)用

1.Application
用戶重寫(xiě)的Application有且只有一個(gè)
2.Activity
啟動(dòng)模式設(shè)置為singleTask的Activity在task中只能存在一個(gè)實(shí)例
3.Service
bindService()啟動(dòng)的Service哪轿,再次啟動(dòng)只會(huì)調(diào)用onStartCommand(),而不會(huì)調(diào)用onCreate()
4.各種Manager
比如WindowManager翔怎、ActivityManager窃诉、PowerManager、ServiceManager等赤套,這些管理類(lèi)對(duì)資源進(jìn)行操作飘痛,為了避免對(duì)同一資源進(jìn)行
操作,而且為了減少資源消耗容握,都采用了單例模式
5.UID
Universal-Image-Loader老牌的圖片加載框架
6.其它的比如EventBus
這個(gè)著名的事件總線框架使用的是DCL的單例模式

4.開(kāi)發(fā)中如何確定使用單例模式

1.當(dāng)創(chuàng)建一個(gè)對(duì)象需要耗費(fèi)過(guò)多的資源或者一個(gè)對(duì)象需要被反復(fù)創(chuàng)建宣脉、銷(xiāo)毀的時(shí)候,如讀取配置等,可以創(chuàng)建一個(gè)單例常駐內(nèi)存,減少資源浪費(fèi)缅刽;
2.當(dāng)需要對(duì)同一個(gè)資源進(jìn)行管理如File叫挟、I/O操作,可以創(chuàng)建單例埃儿,避免對(duì)一個(gè)對(duì)象同時(shí)操作。

5.需要注意的問(wèn)題

單例必定有static操作符,如果持有Activity的context践险,很可能造成Activity無(wú)法釋放,導(dǎo)致OOM吹菱,盡量使用Application的context巍虫;比如有的人喜歡維護(hù)一個(gè)Activity的棧用來(lái)管理Activity,使用不當(dāng)或者一些意外情況會(huì)導(dǎo)致Activity并沒(méi)有被remove鳍刷。

以上就是本人對(duì)單例模式的總結(jié)和思考占遥,能力有限,如有紕漏输瓜,謝謝指出瓦胎。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市尤揣,隨后出現(xiàn)的幾起案子搔啊,更是在濱河造成了極大的恐慌,老刑警劉巖北戏,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件负芋,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡嗜愈,警方通過(guò)查閱死者的電腦和手機(jī)旧蛾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蠕嫁,“玉大人锨天,你說(shuō)我怎么就攤上這事“枰酰” “怎么了绍绘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)迟赃。 經(jīng)常有香客問(wèn)我陪拘,道長(zhǎng),這世上最難降的妖魔是什么纤壁? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任左刽,我火速辦了婚禮,結(jié)果婚禮上酌媒,老公的妹妹穿的比我還像新娘欠痴。我一直安慰自己迄靠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布喇辽。 她就那樣靜靜地躺著掌挚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪菩咨。 梳的紋絲不亂的頭發(fā)上吠式,一...
    開(kāi)封第一講書(shū)人閱讀 49,730評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音抽米,去河邊找鬼特占。 笑死,一個(gè)胖子當(dāng)著我的面吹牛云茸,可吹牛的內(nèi)容都是我干的是目。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼标捺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼懊纳!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起宜岛,我...
    開(kāi)封第一講書(shū)人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤长踊,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后萍倡,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體身弊,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年列敲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阱佛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡戴而,死狀恐怖凑术,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情所意,我是刑警寧澤淮逊,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站扶踊,受9級(jí)特大地震影響泄鹏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜秧耗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一备籽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧分井,春花似錦车猬、人聲如沸霉猛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)惜浅。三九已至,卻和暖如春伏嗜,著一層夾襖步出監(jiān)牢的瞬間赡矢,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工阅仔, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人弧械。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓八酒,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親刃唐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子羞迷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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

  • 目錄 本文的結(jié)構(gòu)如下: 什么是單例模式 為什么要用該模式 模式的結(jié)構(gòu) 代碼示例 優(yōu)點(diǎn)和缺點(diǎn) 適用環(huán)境 模式應(yīng)用 總...
    w1992wishes閱讀 386評(píng)論 1 2
  • 單例模式(Singleton Pattern)是眾多設(shè)計(jì)模式中較為簡(jiǎn)單的一個(gè),同時(shí)它也是面試時(shí)經(jīng)常被提及的問(wèn)題画饥,如...
    廖少少閱讀 556評(píng)論 0 1
  • Java設(shè)計(jì)模式——單例模式 單例模式應(yīng)該是大家最為熟知的一種設(shè)計(jì)模式了衔瓮,相信大家或多或少的都在自己的項(xiàng)目中使用過(guò)...
    gogoingmonkey閱讀 510評(píng)論 0 2
  • 單例模式 介紹 為了節(jié)約系統(tǒng)資源,有時(shí)需要確保系統(tǒng)中某個(gè)類(lèi)只有唯一一個(gè)實(shí)例抖甘,當(dāng)這個(gè)唯一實(shí)例創(chuàng)建成功之后热鞍,我們無(wú)法再...
    666真666閱讀 343評(píng)論 0 6
  • 單例模式(SingletonPattern)一般被認(rèn)為是最簡(jiǎn)單、最易理解的設(shè)計(jì)模式衔彻,也因?yàn)樗暮?jiǎn)潔易懂薇宠,是項(xiàng)目中最...
    成熱了閱讀 4,228評(píng)論 4 34