<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    少年阿賓

    那些青春的歲月

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks
    枚舉單例模式:
    關(guān)于單例模式的實(shí)現(xiàn)有很多種,網(wǎng)上也分析了如今實(shí)現(xiàn)單利模式最好用枚舉,好處不外乎三點(diǎn):
    1.線程安全 2.不會(huì)因?yàn)樾蛄谢a(chǎn)生新實(shí)例 3.防止反射攻擊
    1.線程安全 
    下面這段代碼就是聲明枚舉實(shí)例的通常做法,它可能還包含實(shí)例變量和實(shí)例方法,但是為了簡(jiǎn)單起見,我并沒有使用這些東西,僅僅需要小心的是如果你正在使用實(shí)例方法,那么你需要確保線程安全(如果它影響到其他對(duì)象的狀態(tài)的話)。默認(rèn)枚舉實(shí)例的創(chuàng)建是線程安全的,但是在枚舉中的其他任何方法由程序員自己負(fù)責(zé)。
    關(guān)于線程安全的保證,其實(shí)是通過類加載機(jī)制來保證的,我們看看INSTANCE的實(shí)例化時(shí)機(jī),是在static塊中,JVM加載類的過程顯然是線程安全的。
    static {};
      Code:
       0:   new     #12; //class com/abin/lee/spring/util/Singleton$1
       3:   dup
       4:   ldc     #14; //String INSTANCE
       6:   iconst_0
       7:   invokespecial   #15; //Method com/abin/lee/spring/util/Singleton$1."<init>":(Ljava/lang/String;I)V
       10:  putstatic       #19; //Field INSTANCE:Lcom/abin/lee/spring/util/Singleton;
       13:  iconst_1
       14:  anewarray       #1; //class com/abin/lee/spring/util/Singleton
       17:  dup
       18:  iconst_0
       19:  getstatic       #19; //Field INSTANCE:Lcom/abin/lee/spring/util/Singleton;
       22:  aastore
       23:  putstatic       #21; //Field ENUM$VALUES:[Lcom/abin/lee/spring/util/Singleton;
       26:  return
    線程安全,從反編譯后的類源碼中可以看出也是通過類加載機(jī)制保證的,應(yīng)該是這樣吧

    2.不會(huì)因?yàn)樾蛄谢a(chǎn)生新實(shí)例
    枚舉自己處理序列化
    傳統(tǒng)單例存在的另外一個(gè)問題是一旦你實(shí)現(xiàn)了序列化接口,那么它們不再保持單例了,因?yàn)閞eadObject()方法一直返回一個(gè)新的對(duì)象就像java的構(gòu)造方法一樣,你可以通過使用readResolve()方法來避免此事發(fā)生,看下面的例子:
    //readResolve to prevent another instance of Singleton
        private Object readResolve(){
            return INSTANCE;
        }
    這樣甚至還可以更復(fù)雜,如果你的單例類維持了其他對(duì)象的狀態(tài)的話,因此你需要使他們成為transient的對(duì)象。但是枚舉單例,JVM對(duì)序列化有保證。
    優(yōu)點(diǎn):不僅能避免多線程同步問題,而且還能防止反序列化重新創(chuàng)建新的對(duì)象


    3.防止反射攻擊
    反射攻擊,我有自己試著反射攻擊了以下,不過報(bào)錯(cuò)了...看了下方的反編譯類源碼,明白了,因?yàn)閱卫惖男揎検莂bstract的,所以沒法實(shí)例化。(解決













    靜態(tài)內(nèi)部類:
    // Correct lazy initialization in Java 
    @ThreadSafe
    class Foo {
        private static class HelperHolder {
           public static Helper helper = new Helper();
        }
     
        public static Helper getHelper() {
            return HelperHolder.helper;
        }
    }

    它利用了內(nèi)部靜態(tài)類只有在被引用的時(shí)候才會(huì)被加載的規(guī)律。

    這樣一來,一旦內(nèi)部的HelperHolder被引用了,它就會(huì)首先被JVM加載,進(jìn)行該類的靜態(tài)域的初始化,從而使得Helper這一單例類被初始化。它之所以是線程安全的,也是托了JVM的福,因?yàn)?/span>JVM對(duì)于類的加載這一過程是線程安全的。

    posted on 2015-03-17 15:15 abin 閱讀(357) 評(píng)論(0)  編輯  收藏 所屬分類: PatternDesigns
    主站蜘蛛池模板: 一区二区三区免费在线视频| 亚洲Av无码国产情品久久| GOGOGO高清免费看韩国| 亚洲日韩国产AV无码无码精品| 青青青国产在线观看免费网站| 国产亚洲玖玖玖在线观看| 亚洲国产第一页www| 伊人久久亚洲综合| 69精品免费视频| 99久久婷婷免费国产综合精品| 亚洲精品自在线拍| 亚洲AV永久无码精品成人| 国产精品亚洲产品一区二区三区 | 一级毛片a免费播放王色电影| 亚洲成A人片777777| 中文字幕亚洲激情| 免费一级肉体全黄毛片| 日本免费电影一区| 欧美日韩国产免费一区二区三区 | 在线观看免费a∨网站| 四虎在线视频免费观看视频| 日本视频免费高清一本18| 亚洲婷婷第一狠人综合精品| 亚洲欧洲中文日产| 亚洲最新在线视频| 亚洲欧洲视频在线观看| 亚洲欧洲久久久精品| 一本色道久久88亚洲综合| 免费在线观看日韩| 国产免费人成在线视频| 日本免费一区二区三区| 一区二区三区观看免费中文视频在线播放 | 亚洲成av人在片观看| 国产a级特黄的片子视频免费| 久草视频在线免费看| 国产精品免费一区二区三区四区| 亚洲AV性色在线观看| 亚洲综合在线成人一区| 亚洲人成电影院在线观看| 亚洲一区二区三区播放在线| 亚洲永久在线观看|