設(shè)計(jì)模式學(xué)習(xí)(五)——單例模式

一.需求

在遙遠(yuǎn)的山村集侯,由于交通不便慎宾,物資匱泛,很多生活必需品都供應(yīng)不足浅悉。家家戶戶都需要吃的食鹽便是如此趟据。村里有幾家雜貨店供應(yīng)日常用品,油鹽醬醋倒是都有供應(yīng)术健,但是食鹽卻是常常供不應(yīng)求汹碱,主要是因?yàn)槭雏}需要從很遠(yuǎn)的地方才可以進(jìn)貨,而由于交通不便每次又運(yùn)不了太多荞估。

時(shí)間長(zhǎng)了咳促,幾家雜貨店的老板看到了其中的商機(jī)。有的囤貨不賣勘伺,等其他幾家賣完后加價(jià)出售跪腹;有的以次充好,銷售劣質(zhì)食鹽飞醉;有時(shí)冲茸,幾家雜貨店老版甚至集體漲價(jià)。種種伎倆,到頭來吃虧的都是普通村民們轴术。

村長(zhǎng)也想過很多辦法規(guī)范食鹽銷售难衰,但是由于交通的根本問題一直得不到解決,每次嚴(yán)厲懲治后不久逗栽,雜貨店就變相漲價(jià)盖袭,道高一尺,魔高一丈彼宠■看來,必須要想一個(gè)徹底解決問題的辦法凭峡。

二.解決方案

經(jīng)過村委會(huì)討論拙已,大家想出一個(gè)好辦法:村委會(huì)出資采購(gòu)食鹽,平價(jià)銷售想罕。幾個(gè)雜貨店一看再也漲不了價(jià)了悠栓,食鹽的進(jìn)貨又很麻煩,索性都不再銷售食鹽了按价。這樣一來惭适,村里只有一個(gè)食鹽銷售的渠道,那就是村委會(huì)楼镐,再也沒有了過去的種種煩惱癞志,村民們無比擁護(hù)。

對(duì)比一下前后兩種食鹽銷售途徑:

第一種:多家雜貨店同時(shí)銷售

這種方式的問題是:每家銷售的食鹽價(jià)格不統(tǒng)一框产,質(zhì)量不統(tǒng)一凄杯。

第二種:村委會(huì)統(tǒng)一銷售

這種方法的好處是:銷售的食鹽價(jià)格統(tǒng)一,質(zhì)量穩(wěn)定

兩相對(duì)比秉宿,可以看出戒突,針對(duì)食鹽銷售這個(gè)場(chǎng)景,統(tǒng)一銷售要好于多家零散銷售描睦。

三.模式總結(jié)

我們上面采用的統(tǒng)一銷售的方式其實(shí)已經(jīng)使用了單例模式的思想:全局中只有一個(gè)實(shí)例膊存,并提供一個(gè)全局的訪問點(diǎn)。

類圖
單例模式類圖
使用場(chǎng)景

系統(tǒng)只需要一個(gè)實(shí)例對(duì)象忱叭,如系統(tǒng)需要生產(chǎn)唯一的序列號(hào)隔崎,則序列號(hào)生成器最好由唯一對(duì)象統(tǒng)一生成。

優(yōu)點(diǎn)

(1)提供唯一可以訪問的實(shí)例對(duì)象韵丑,從而可以更好的控制用戶行為
(2)由于只有一個(gè)實(shí)例爵卒,可以減少系統(tǒng)開銷

缺點(diǎn)

由于單例類是某個(gè)具體的類,而不是接口撵彻,因此擴(kuò)展性不足

幾種實(shí)現(xiàn)方式
方法一:靜態(tài)初始化
public class Singleton {
    // 初始化階段完成實(shí)例創(chuàng)建
    private static Singleton instance = new Singleton();
    
    // 將構(gòu)造方法聲明為私有钓株,保證類外部無法調(diào)用
    private Singleton() {}
    
    public static Singleton getInstance() {
        return instance;
    }
}
方法二:延遲實(shí)例化

方法一中实牡,實(shí)現(xiàn)過程簡(jiǎn)單,而且能保證線程安全享幽,但是有一個(gè)缺點(diǎn):不管instance最終有沒有被用到铲掐,都已經(jīng)被實(shí)例化拾弃,有可能造成資源浪費(fèi)值桩。另一類方法是延遲實(shí)例化:

// 線程不安全的單例模式
public class Singleton {
    private static Singleton instance;

    // 將構(gòu)造方法聲明為私有,保證類外部無法調(diào)用
    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

上面代碼是線程不安全的豪椿,在多線程環(huán)境下奔坟,有可能創(chuàng)建出多個(gè)Singleton實(shí)例。

如果考慮到線程安全搭盾,有幾種辦法:

// 線程安全的單例模式
public class Singleton {
    private static Singleton instance;

    // 將構(gòu)造方法聲明為私有咳秉,保證類外部無法調(diào)用
    private Singleton() {}

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

注意到我們對(duì)getInstance方法進(jìn)行了同步操作,保證同一時(shí)刻鸯隅,只能有一個(gè)線程進(jìn)入方法體澜建。但是由于同步操作會(huì)降低性能,實(shí)時(shí)上蝌以,一旦完成初始化后炕舵,就不需要再進(jìn)行同步了,實(shí)際上是另一種資源浪費(fèi)跟畅。

雙重檢查加鎖:

// 線程安全的單例模式
public class Singleton {
    private volatile static Singleton instance;

    // 將構(gòu)造方法聲明為私有咽筋,保證類外部無法調(diào)用
    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) { // 如果確實(shí)沒有被實(shí)例化,才進(jìn)行實(shí)例化
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

在這個(gè)實(shí)現(xiàn)中徊件,一旦完成實(shí)例化奸攻,就不會(huì)再進(jìn)入synchronized同步塊鳄哭,從而不會(huì)造成性能問題静稻。

參考資料

本文已遷移至我的博客:http://ipenge.com/52281.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市括享,隨后出現(xiàn)的幾起案子部翘,更是在濱河造成了極大的恐慌硝训,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件略就,死亡現(xiàn)場(chǎng)離奇詭異捎迫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)表牢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門窄绒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人崔兴,你說我怎么就攤上這事彰导』壮幔” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵位谋,是天一觀的道長(zhǎng)山析。 經(jīng)常有香客問我,道長(zhǎng)掏父,這世上最難降的妖魔是什么笋轨? 我笑而不...
    開封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮赊淑,結(jié)果婚禮上爵政,老公的妹妹穿的比我還像新娘。我一直安慰自己陶缺,他們只是感情好钾挟,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著饱岸,像睡著了一般掺出。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上苫费,一...
    開封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天汤锨,我揣著相機(jī)與錄音,去河邊找鬼黍衙。 笑死泥畅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的琅翻。 我是一名探鬼主播位仁,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼方椎!你這毒婦竟也來了聂抢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤棠众,失蹤者是張志新(化名)和其女友劉穎琳疏,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闸拿,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡空盼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了新荤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片揽趾。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖苛骨,靈堂內(nèi)的尸體忽然破棺而出篱瞎,到底是詐尸還是另有隱情苟呐,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布俐筋,位于F島的核電站牵素,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏澄者。R本人自食惡果不足惜笆呆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望闷哆。 院中可真熱鬧腰奋,春花似錦单起、人聲如沸抱怔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)屈留。三九已至,卻和暖如春测蘑,著一層夾襖步出監(jiān)牢的瞬間灌危,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工碳胳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留勇蝙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓挨约,卻偏偏與公主長(zhǎng)得像味混,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诫惭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

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