設(shè)計模式系列-單例模式

1 單例模式

單例模式:確保某一個類只有一個實例,自行實例化并向整個系統(tǒng)提供這個實例怯伊。

使用場景

確保某個類只有一個對象的場景肆糕,避免產(chǎn)生多個對象消耗資源,或者某個對象應(yīng)該有且只有一個的場景篙议。

特點

1.構(gòu)造函數(shù)不對外開放唾糯,一般為private

2.通過靜態(tài)方法返回單例類的對象

3.確保對象只有一個,尤其是在多線程的情況下

4.確保單例類對象在反序列化時不會重新創(chuàng)建對象

寫單例

一:餓漢模式

    public class Singleton {
        private static final Singleton singleton = new Singleton();
        private Singleton(){
        }
        public static Singleton getInstance(){
            return singleton;
        }
        //  do.....
    }

二:懶漢模式

    public class SingletonV2 {
        private static SingletonV2 singletonV2 = null;
        private SingletonV2(){
        }
        public static synchronized SingletonV2 getInstance(){
            if(singletonV2 != null){
                singletonV2 = new SingletonV2();
            }
            return singletonV2;
        }
        // do....
    }

優(yōu)點:只有在使用時才會被實例化
缺點:每次使用都要進(jìn)行同步鬼贱,即使單例已經(jīng)存在移怯,造成不必要的同步開銷

三:DCL實現(xiàn)單例(雙鎖)

    public class SingletonV3 {
        private static SingletonV3 singletonV3 = null;
        private SingletonV3(){
        }
        public static SingletonV3 getInstance(){
            if(singletonV3 == null){
                synchronized (SingletonV3.class){
                    if(singletonV3 == null){
                        singletonV3 = new SingletonV3();
                    }
                }
            }
            return singletonV3;
        }
        // do ....
    }

DCL失效問題:

singletonV3 = new SingletonV3(); 一句代碼,卻不是原子性操作这难,會被編譯成多條匯編指令舟误,但大致作了三件事:

1.給SingletonV3的實例分配內(nèi)存;

2.調(diào)用SingletonV3的構(gòu)造函數(shù)姻乓,初始化字段嵌溢;

3.將singletonV3指向分配的內(nèi)存空間(這時singletonV3 不為 null)

JDK1.5之前java編譯器允許處理器亂序執(zhí)行,上面2蹋岩,3的執(zhí)行順序是無法保證的赖草,所以執(zhí)行順序可能是1-2-3,也可能是1-3-2剪个,如果是后者疚顷,則有可能出現(xiàn)3執(zhí)行完畢,2還未執(zhí)行禁偎,此時singletonV3已經(jīng)不為null腿堤,但另一個線程取走singletonV3,使用就會出錯如暖。

jdk1.5之后笆檀,使用volatile,修改為private volatile static SingletonV3 singletonV3 = null;就可以保證singletonV3保證每次都是從主內(nèi)存中讀取盒至。

能夠在絕大多數(shù)情況保證單例對象的唯一性酗洒,除非在并發(fā)場景比較復(fù)雜或JDK低于6的版本下使用。

四:靜態(tài)內(nèi)部類實現(xiàn)

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

第一次加載SingletonV4時并不會初始化singletonV4枷遂,只有第一次調(diào)用getInstance()才會導(dǎo)致加載SingletonHolder類樱衷,線程安全,而且保證對象的唯一性酒唉,切延遲實例化矩桂,推薦的單例實現(xiàn)方式。

五:枚舉實現(xiàn)單例

public enum SIngletonEnum {
    Instance;
    // do something
    private int num = 10;
    public int doSomething(){
        return num;
    }
    //
}

枚舉單例的最大特點就是簡單痪伦,枚舉不僅能夠有字段侄榴,還能夠有方法雹锣,枚舉單例是線程安全的。

反序列化

序列化操作提供了一個很特別的鉤子(hook)-類中具有一個私有的被實例化的方法readresolve(),這個方法可以確保類的開發(fā)人員在序列化將會返回怎樣的object上具有發(fā)言權(quán)癞蚕。

     private Object readResolve() throws ObjectStreamException {
         return getInstance();
     }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蕊爵,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子桦山,更是在濱河造成了極大的恐慌攒射,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恒水,死亡現(xiàn)場離奇詭異匆篓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)寇窑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門鸦概,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人甩骏,你說我怎么就攤上這事窗市。” “怎么了饮笛?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵咨察,是天一觀的道長。 經(jīng)常有香客問我福青,道長摄狱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任无午,我火速辦了婚禮媒役,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宪迟。我一直安慰自己酣衷,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布次泽。 她就那樣靜靜地躺著穿仪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪意荤。 梳的紋絲不亂的頭發(fā)上啊片,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機(jī)與錄音玖像,去河邊找鬼紫谷。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碴里。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼上真,長吁一口氣:“原來是場噩夢啊……” “哼咬腋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起睡互,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤根竿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后就珠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寇壳,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年妻怎,在試婚紗的時候發(fā)現(xiàn)自己被綠了壳炎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡逼侦,死狀恐怖匿辩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情榛丢,我是刑警寧澤铲球,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站晰赞,受9級特大地震影響稼病,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掖鱼,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一然走、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧戏挡,春花似錦丰刊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掌栅,卻和暖如春秩仆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背猾封。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工澄耍, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓齐莲,卻偏偏與公主長得像痢站,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子选酗,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

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