枚舉實(shí)現(xiàn)單例模式

1.引言

單元素的枚舉類型已經(jīng)成為實(shí)現(xiàn)Singleton的最佳方法
????????????????????? -- 出自 《effective java》

2.單例模式的特點(diǎn)

  • 單例模式三個(gè)主要特點(diǎn):
    1、構(gòu)造方法私有化赋访;
    2佣耐、實(shí)例化的變量引用私有化;
    3、獲取實(shí)例的方法共有益楼。

3. 常用的單例模式

1.單例的餓漢模式

 1   public class Singleton {
 2     /*
 3      * 利用靜態(tài)變量來記錄Singleton的唯一實(shí)例
 4      * 直接初始化靜態(tài)變量氧秘,這樣就可以確保線程安全了
 5      */
 6     private static Singleton uniqueInstance = new Singleton();
 7
 8     /*
 9      * 構(gòu)造器私有化,只有Singleton類內(nèi)才可以調(diào)用構(gòu)造器
10      */
11     private Singleton(){
12
13     }
14
15     public static Singleton getInstance(){
16         return uniqueInstance;
17     }
18
19 }

2.懶漢的雙重加鎖機(jī)制

 1 public class Singleton {
 2     /*
 3      * 利用靜態(tài)變量來記錄Singleton的唯一實(shí)例
 4      * volatile 關(guān)鍵字確保:當(dāng)uniqueInstance變量被初始化成Singleton實(shí)例時(shí),
 5      * 多個(gè)線程正確地處理uniqueInstance變量
 6      *
 7      */
 8     private volatile static Singleton uniqueInstance;
 9
10     /*
11      * 構(gòu)造器私有化赌蔑,只有Singleton類內(nèi)才可以調(diào)用構(gòu)造器
12      */
13     private Singleton(){
14
15     }
16
17     /*
18      *
19      * 檢查實(shí)例俯在,如果不存在,就進(jìn)入同步區(qū)域
20      */
21     public static Singleton getInstance(){
22         if(uniqueInstance == null){
23             synchronized(Singleton.class){    //進(jìn)入同步區(qū)域
24                 if(uniqueInstance == null){     //在檢查一次娃惯,如果為null跷乐,則創(chuàng)建
25                     uniqueInstance  = new Singleton();
26                 }
27             }
28         }
29
30         return uniqueInstance;
31     }
32
33 }

3.靜態(tài)內(nèi)部類

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

4.為什么使用單例

4.1 私有化構(gòu)造器并不保險(xiǎn)

    《effective java》中只簡單的提了幾句話:“享有特權(quán)的客戶端可以借助AccessibleObject.setAccessible方法,通過反射機(jī)制調(diào)用私有構(gòu)造器趾浅。如果需要低于這種攻擊愕提,可以修改構(gòu)造器,讓它在被要求創(chuàng)建第二個(gè)實(shí)例的時(shí)候拋出異常皿哨。

4.2序列化問題

    任何一個(gè)readObject方法浅侨,不管是顯式的還是默認(rèn)的,它都會(huì)返回一個(gè)新建的實(shí)例证膨,這個(gè)新建的實(shí)例不同于該類初始化時(shí)創(chuàng)建的實(shí)例如输。”當(dāng)然央勒,這個(gè)問題也是可以解決的不见,想詳細(xì)了解的同學(xué)可以翻看《effective java》第77條:對(duì)于實(shí)例控制,枚舉類型優(yōu)于readResolve

4.3 枚舉單例示例

public enum  EnumSingleton {
    INSTANCE;
    public EnumSingleton getInstance(){
        return INSTANCE;
    }
}

單例模式


public class User {
    //私有化構(gòu)造函數(shù)
    private User(){ }
 
    //定義一個(gè)靜態(tài)枚舉類
    static enum SingletonEnum{
        //創(chuàng)建一個(gè)枚舉對(duì)象崔步,該對(duì)象天生為單例
        INSTANCE;
        private User user;
        //私有化枚舉的構(gòu)造函數(shù)
        private SingletonEnum(){
            user=new User();
        }
        public User getInstnce(){
            return user;
        }
    }
 
    //對(duì)外暴露一個(gè)獲取User對(duì)象的靜態(tài)方法
    public static User getInstance(){
        return SingletonEnum.INSTANCE.getInstnce();
    }
}

public class Test {
    public static void main(String [] args){
        System.out.println(User.getInstance());
        System.out.println(User.getInstance());
        System.out.println(User.getInstance()==User.getInstance());
    }
}
結(jié)果為true

以上代碼看起來已經(jīng)是ok了稳吮,其實(shí)不是,可能還存在反射攻擊或者反序列化攻擊

最終版

public enum Singleton {

    INSTANCE;

    public void doSomething() {
        System.out.println("doSomething");
    }

}
調(diào)用方法:

public class Main {

    public static void main(String[] args) {
        Singleton.INSTANCE.doSomething();
    }

}

直接通過Singleton.INSTANCE.doSomething()的方式調(diào)用即可井濒。方便灶似、簡潔又安全。

5.總結(jié)

至此瑞你,相信大家應(yīng)該能明白了為什么Joshua Bloch說的“單元素的枚舉類型已經(jīng)成為實(shí)現(xiàn)Singleton的最佳方法”了吧喻奥。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市捏悬,隨后出現(xiàn)的幾起案子撞蚕,更是在濱河造成了極大的恐慌,老刑警劉巖过牙,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甥厦,死亡現(xiàn)場離奇詭異,居然都是意外死亡寇钉,警方通過查閱死者的電腦和手機(jī)刀疙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扫倡,“玉大人谦秧,你說我怎么就攤上這事竟纳。” “怎么了疚鲤?”我有些...
    開封第一講書人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵锥累,是天一觀的道長。 經(jīng)常有香客問我集歇,道長桶略,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任诲宇,我火速辦了婚禮际歼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘姑蓝。我一直安慰自己鹅心,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開白布纺荧。 她就那樣靜靜地躺著旭愧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪虐秋。 梳的紋絲不亂的頭發(fā)上榕茧,一...
    開封第一講書人閱讀 49,985評(píng)論 1 291
  • 那天垃沦,我揣著相機(jī)與錄音客给,去河邊找鬼。 笑死肢簿,一個(gè)胖子當(dāng)著我的面吹牛靶剑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播池充,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼桩引,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了收夸?” 一聲冷哼從身側(cè)響起坑匠,我...
    開封第一講書人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎卧惜,沒想到半個(gè)月后厘灼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡咽瓷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年设凹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茅姜。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡闪朱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奋姿,我是刑警寧澤锄开,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站胀蛮,受9級(jí)特大地震影響院刁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜粪狼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一退腥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧再榄,春花似錦狡刘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疾就,卻和暖如春澜术,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背猬腰。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來泰國打工鸟废, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人姑荷。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓盒延,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鼠冕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子添寺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

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

  • 枚舉單例(Enum Singleton)是實(shí)現(xiàn)單例模式的一種新方式,盡管單例模式在java中已經(jīng)存在很長時(shí)間了懈费,但...
    淡淡的傷你閱讀 1,176評(píng)論 0 3
  • 枚舉實(shí)現(xiàn)單例模式 前面我們說到序列化和反序列化以及反射對(duì)單例都是有破壞的计露,下面我們介紹一種更加優(yōu)雅的實(shí)現(xiàn),也是ef...
    三不猴子閱讀 3,465評(píng)論 0 1
  • 單例模式(SingletonPattern)一般被認(rèn)為是最簡單憎乙、最易理解的設(shè)計(jì)模式票罐,也因?yàn)樗暮啙嵰锥琼?xiàng)目中最...
    成熱了閱讀 4,231評(píng)論 4 34
  • 微信原文:設(shè)計(jì)模式 | 單例模式及典型應(yīng)用 單例是最常見的設(shè)計(jì)模式之一寨闹,實(shí)現(xiàn)的方式非常多胶坠,同時(shí)需要注意的問題也非常...
    小旋鋒的簡書閱讀 1,775評(píng)論 2 5
  • 前言 EFK可能都不熟悉,實(shí)際上EFK是大名鼎鼎的日志系統(tǒng)ELK的一個(gè)變種 在沒有分布式日志的時(shí)候繁堡,每次出問題了需...
    Raye閱讀 30,143評(píng)論 0 28