設(shè)計(jì)模式之單例(java語言)

單例模式確保某個(gè)類只有一個(gè)實(shí)例改基,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例暑诸。

Singleton通過將構(gòu)造方法限定為private避免了類在外部被實(shí)例化县恕,在同一個(gè)虛擬機(jī)范圍內(nèi)惨缆,Singleton的唯一實(shí)例只能通過getInstance()方法訪問(事實(shí)上糜值,通過Java反射機(jī)制是能夠?qū)嵗瘶?gòu)造方法為private的類的,那基本上會(huì)使所有的Java單例實(shí)現(xiàn)失效坯墨。此問題在此處不做討論寂汇。)

單例模式有以下特點(diǎn):
  1. 單例類只能有一個(gè)實(shí)例
  2. 單例類必須自己創(chuàng)建自己的唯一實(shí)例
  3. 單例類必須給所有其他對象提供這一實(shí)例
單例模式有以下有點(diǎn):
  1. 由于只有一個(gè)實(shí)例,故可以減少內(nèi)存開銷
  2. 可以避免對資源的多重占用捣染,避免對同一資源進(jìn)行多種操作
  3. 設(shè)置了全局的資源訪問骄瓣,可以優(yōu)化和共享全局資源訪問
單例模式的幾種實(shí)現(xiàn)方法
  • 懶漢單例
public class Singleton {
    private static Singleton single=null;
    private Singleton() {    }
    public static Singleton getInstance() {
        if(single==null) {
            single=new Singleton();
        }
        return single;
    }
}
特點(diǎn):在第一次調(diào)用的時(shí)候?qū)嵗约?優(yōu)點(diǎn):在需要的時(shí)候才去加載
缺點(diǎn):在多線程的環(huán)境下,會(huì)出現(xiàn)線性不安全的情況

懶漢式單例的實(shí)現(xiàn)沒有考慮線程安全問題耍攘,它是線程不安全的榕栏,并發(fā)環(huán)境下很可能出現(xiàn)多個(gè)Singleton實(shí)例畔勤,要實(shí)現(xiàn)線程安全,有以下三種方式扒磁,都是對getInstance這個(gè)方法改造庆揪,保證了懶漢式單例的線程安全.

1.1 在getInstance方法上加同步
public class Singleton {
    private static Singleton single=null;
    private Singleton() {    }
    public static synchronized Singleton getInstance() {
        if(single==null) {
            single=new Singleton();
        }
        return single;
    }
}
優(yōu)點(diǎn):解決了線性同步問題
缺點(diǎn):每次調(diào)用都要判斷同步鎖,導(dǎo)致效率低
1.2 雙重檢查鎖
public class Singleton {
    private static Singleton single=null;
    private Singleton() {    }
    public static Singleton getInstance() {
        if(single==null) {
            synchronized(Singleton.class) {
                if(single==null) {
                    single=new Singleton();
                }
            }
        }
        return single;
    }
}
優(yōu)點(diǎn):在并發(fā)量不高妨托、安全性不高的情況下可以很好的運(yùn)行,在getInstance中做了兩次null檢查缸榛,
確保了只有第一次調(diào)用單例的時(shí)候才會(huì)做同步,這樣也是線程安全的兰伤,同時(shí)避免了每次都同步的性能損耗
缺點(diǎn):在不同的編譯環(huán)境下可能出現(xiàn)不同的問題
1.3 靜態(tài)內(nèi)部類
public class Singleton {
    private static class Holder {
        private static final Singleton INSTANCE=new Singleton();
    }
    private Singleton() {    }
    public static final Singleton getInstance() {
        return Holder.INSTANCE;
    }
}
優(yōu)點(diǎn):延遲加載内颗、線性安全、減少內(nèi)存消耗
這種比上面1.1敦腔、1.2都好一些均澳,既實(shí)現(xiàn)了線程安全,又避免了同步帶來的性能影響符衔。
  • 餓漢單例
public class Singleton {
    private Singleton() {}
    private static final Singleton single=new Singleton();
    //靜態(tài)工廠方法
    public static Singleton getInstance() {
        return single;
    }
}
特點(diǎn):在類初始化時(shí)找前,已經(jīng)自行實(shí)例化
餓漢式在類創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對象供系統(tǒng)使用,以后不再改變柏腻,所以天生是線程安全的纸厉。
  • 枚舉
public enum Singleton {
    INSTANCE;
    public void whateverMethod() {    }
}
它不僅能避免多線程同步問題,而且還能防止反序列化重新創(chuàng)建新的對象五嫂,可謂是很堅(jiān)強(qiáng)的壁壘啊颗品,不過,個(gè)人認(rèn)為由于1.5中才加入enum特性沃缘,用這種方式寫不免讓人感覺生疏躯枢,在實(shí)際工作中,我也很少看見有人這么寫過槐臀。
餓漢式和懶漢式區(qū)別 :
  • 餓漢就是類一旦加載锄蹂,就把單例初始化完成,保證getInstance的時(shí)候水慨,單例是已經(jīng)存在的了得糜,
  • 而懶漢比較懶朝抖,只有當(dāng)調(diào)用getInstance的時(shí)候治宣,才回去初始化這個(gè)單例。
  • 餓漢式天生就是線程安全的,可以直接用于多線程而不會(huì)出現(xiàn)問題侮邀,
  • 懶漢式本身是非線程安全的坏怪,為了實(shí)現(xiàn)線程安全有幾種寫法,分別是上面的1.1绊茧、1.2铝宵、1.3,這三種實(shí)現(xiàn)在資源加載和性能方面有些區(qū)別按傅。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末捉超,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子枝誊,更是在濱河造成了極大的恐慌况芒,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叶撒,死亡現(xiàn)場離奇詭異绝骚,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)古瓤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門止剖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人落君,你說我怎么就攤上這事穿香。” “怎么了绎速?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵皮获,是天一觀的道長。 經(jīng)常有香客問我纹冤,道長洒宝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任萌京,我火速辦了婚禮雁歌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘枫夺。我一直安慰自己将宪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著较坛,像睡著了一般印蔗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丑勤,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天华嘹,我揣著相機(jī)與錄音,去河邊找鬼法竞。 笑死耙厚,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的岔霸。 我是一名探鬼主播薛躬,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼呆细!你這毒婦竟也來了型宝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤絮爷,失蹤者是張志新(化名)和其女友劉穎趴酣,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坑夯,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岖寞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了柜蜈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仗谆。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖跨释,靈堂內(nèi)的尸體忽然破棺而出胸私,到底是詐尸還是另有隱情,我是刑警寧澤鳖谈,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布岁疼,位于F島的核電站,受9級特大地震影響缆娃,放射性物質(zhì)發(fā)生泄漏捷绒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一贯要、第九天 我趴在偏房一處隱蔽的房頂上張望暖侨。 院中可真熱鬧,春花似錦崇渗、人聲如沸字逗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽葫掉。三九已至些举,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間俭厚,已是汗流浹背户魏。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挪挤,地道東北人叼丑。 一個(gè)月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像扛门,于是被迫代替她去往敵國和親鸠信。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

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