你真的會(huì)用單例模式嗎配并?

一光酣、簡介:

 我們經(jīng)常有這樣的需求:  某一些類應(yīng)該只存在一個(gè)實(shí)例  的時(shí)候,我們就可以用單例模式來應(yīng)對(duì).

單例模式:確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn).

單例模式是所有設(shè)計(jì)模式中最簡單的一個(gè),也是大部分人最早知道的一個(gè)設(shè)計(jì)模式.

二勾缭、我們經(jīng)常用的2種單例模式(懶漢式揍障、餓漢式)

(1)餓漢式:

餓漢式單例類.在類初始化時(shí),已經(jīng)自行實(shí)例化

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

餓漢式在類創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對(duì)象供系統(tǒng)使用俩由,以后不再改變毒嫡,所以是線程安全的岩齿。

(2)懶漢式

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

備注


Paste_Image.png
 單例模式的懶漢式實(shí)現(xiàn)方式體現(xiàn)了延遲加載的思想舞吭,什么是延遲加
載呢刨仑?  通俗點(diǎn)說拷泽,就是一開始不要加載
資源或者數(shù)據(jù),一直等咬摇,等到馬上就要使用這個(gè)資源或者數(shù)據(jù)了伐蒂,躲不過去了才加載,所以也稱
Lazy Load肛鹏,不是懶惰啊逸邦,是“延遲加載”,這在實(shí)際開發(fā)中是一種很常見的思想在扰,盡可能的節(jié)約資源缕减。
   單例模式的懶漢式實(shí)現(xiàn)還體現(xiàn)了緩存的思想,緩存也是實(shí)際開發(fā)中非常常見的功能芒珠。簡單講就是桥狡,如果
某些資源或者數(shù)據(jù)會(huì)被頻繁的使用,而這些資源或數(shù)據(jù)存儲(chǔ)在系統(tǒng)外部皱卓,比如數(shù)據(jù)庫裹芝、硬盤文件等,
那么每次操作這些數(shù)據(jù)的時(shí)候都從數(shù)據(jù)庫或者硬盤上去獲取好爬,速度會(huì)很慢局雄,會(huì)造成性能問題。 一個(gè)簡單的
解決方法就是:把這些數(shù)據(jù)緩存到內(nèi)存里面存炮,每次操作的時(shí)候,先到內(nèi)存里面找蜈漓,看有沒有這些數(shù)據(jù)穆桂,
如果有,那么就直接使用融虽,如果沒有那么就獲取它享完,并設(shè)置到緩存中,下一次訪問的時(shí)候就可以直接從內(nèi)存
中獲取了有额。從而節(jié)省大量的時(shí)間般又,當(dāng)然,緩存是一種典型的空間換時(shí)間的方案巍佑。

兩種單例模式的比較

比較上面兩種寫法:
1茴迁、懶漢式是典型的時(shí)間換空間,也就是每次獲取實(shí)例都會(huì)進(jìn)行判斷萤衰,看是否需要?jiǎng)?chuàng)建實(shí)例堕义,費(fèi)判斷的時(shí)間,當(dāng)然脆栋,如果一直沒有人使用的話倦卖,那就不會(huì)創(chuàng)建實(shí)例洒擦,節(jié)約內(nèi)存空間。
2怕膛、 餓漢式是典型的空間換時(shí)間熟嫩,當(dāng)類裝載的時(shí)候就會(huì)創(chuàng)建類實(shí)例,不管你用不用褐捻,先創(chuàng)建出來邦危,然后每次調(diào)用的時(shí)候,就不需要再判斷了舍扰,節(jié)省了運(yùn)行時(shí)間倦蚪。

(3)雙重檢查加鎖

public class Singleton {        

        private volatile static Singleton instance = null;
        private Singleton() {}
        public static Singleton getInstance() {
            //先檢查實(shí)例是否存在,如果不存在才進(jìn)入下面的同步塊
            if (instance == null) {
                //同步塊边苹,線程安全的創(chuàng)建實(shí)例
                synchronized (Singleton.class) {
                    //再次檢查實(shí)例是否存在陵且,如果不存在才真的創(chuàng)建實(shí)例
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }

雙重檢查詳解
可以使用“雙重檢查加鎖”的方式來實(shí)現(xiàn),就可以既實(shí)現(xiàn)線程安全个束,又能夠使性能不受到大的影響慕购。
那么什么是“雙重檢查加鎖”機(jī)制呢? 所謂雙重檢查加鎖機(jī)制茬底,指的是:并不是每次進(jìn)入getInstance方法都需要同步沪悲,而是先不同步,進(jìn)入方法過后阱表,先檢查實(shí)例是否存在殿如,如果不存在才進(jìn)入下面的同步塊,這是第一重檢查最爬。進(jìn)入同步塊過后涉馁,再次檢查實(shí)例是否存在,如果不存在爱致,就在同步的情況下創(chuàng)建一個(gè)實(shí)例烤送,這是第二重檢查。這樣一來糠悯,就只需要同步一次了帮坚,從而減少了多次在同步情況下進(jìn)行判斷所浪費(fèi)的時(shí)間。 雙重檢查加鎖機(jī)制的實(shí)現(xiàn)會(huì)使用一個(gè)關(guān)鍵字volatile互艾,它的意思是:被volatile修飾的變量的值试和,將不會(huì)被本地線程緩存,所有對(duì)該變量的讀寫都是直接操作共享內(nèi)存,從而確保多個(gè)線程能正確的處理該變量忘朝。 這種實(shí)現(xiàn)方式既可使實(shí)現(xiàn)線程安全的創(chuàng)建實(shí)例灰署,又不會(huì)對(duì)性能造成太大的影響,它只是在第一次創(chuàng)建實(shí)例的時(shí)候同步,以后就不需要同步了溉箕,從而加快運(yùn)行速度晦墙。 注意:在Java1.4及以前版本中,很多JVM對(duì)于volatile關(guān)鍵字的實(shí)現(xiàn)有問題肴茄,會(huì)導(dǎo)致雙重檢查加鎖的失敗晌畅,因此雙重檢查加鎖的機(jī)制只能用在Java5及以上的版本。

(4)寡痰、靜態(tài)內(nèi)部類單例模式

public class Singleton {

        private static class Holder{
            private static Singleton INSTANCE = new Singleton();
        }
        public static Singleton getInstance(){
            return Holder.INSTANCE;
        }
    }

當(dāng)?shù)谝淮渭虞dSingleton類時(shí)并不會(huì)初始化INSTANCE抗楔,只有在第一次調(diào)用getInstance方法時(shí)才會(huì)導(dǎo)致INSTANCE被初始化。這種方式不僅能夠保證線程安全拦坠,也能保證單例對(duì)象的唯一性连躏,同時(shí)也延長了單例的實(shí)例化。

小結(jié)

1贞滨、雙重檢查非常適用于高并發(fā),我們熟知的開源庫Eventbus,ImageLoader等都是用的雙重檢查鎖方式實(shí)現(xiàn)單例

2入热、單例模式是運(yùn)用頻率很高的模式,但是晓铆,由于在客戶端通常沒有高并發(fā)的情況勺良,因此,選擇哪種實(shí)現(xiàn)方式都不會(huì)有太大的影響骄噪。即使如此尚困,出于效率考慮,推薦使用DCL單例(雙重檢查鎖定)和靜態(tài)內(nèi)部類單例模式链蕊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末事甜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子示弓,更是在濱河造成了極大的恐慌讳侨,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奏属,死亡現(xiàn)場離奇詭異,居然都是意外死亡潮峦,警方通過查閱死者的電腦和手機(jī)囱皿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忱嘹,“玉大人嘱腥,你說我怎么就攤上這事【性茫” “怎么了齿兔?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我分苇,道長添诉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任医寿,我火速辦了婚禮栏赴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘靖秩。我一直安慰自己须眷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布沟突。 她就那樣靜靜地躺著花颗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪惠拭。 梳的紋絲不亂的頭發(fā)上扩劝,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天,我揣著相機(jī)與錄音求橄,去河邊找鬼今野。 笑死,一個(gè)胖子當(dāng)著我的面吹牛罐农,可吹牛的內(nèi)容都是我干的条霜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼涵亏,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼宰睡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起气筋,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤拆内,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后宠默,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體麸恍,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年搀矫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抹沪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瓤球,死狀恐怖融欧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情卦羡,我是刑警寧澤噪馏,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布麦到,位于F島的核電站,受9級(jí)特大地震影響欠肾,放射性物質(zhì)發(fā)生泄漏瓶颠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一董济、第九天 我趴在偏房一處隱蔽的房頂上張望步清。 院中可真熱鬧,春花似錦虏肾、人聲如沸廓啊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谴轮。三九已至,卻和暖如春吹埠,著一層夾襖步出監(jiān)牢的瞬間第步,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國打工缘琅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留粘都,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓刷袍,卻偏偏與公主長得像翩隧,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子呻纹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

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