設(shè)計(jì)模式·單例模式

1还栓、餓漢式

  • 優(yōu)點(diǎn):類加載的時(shí)候完成實(shí)例化碌廓,避免了線程同步問題
  • 缺點(diǎn):在類加載的時(shí)候就完成實(shí)例化,沒有達(dá)到Lazy Loading的效果剩盒,如果該類未使用則造成了內(nèi)存浪費(fèi)

可以通過靜態(tài)變量和靜態(tài)代碼塊兩種方式實(shí)現(xiàn)谷婆,效果一樣

public class Singleton1 {
   //方式1:通過靜態(tài)變量方式創(chuàng)建
   private static final Singleton1 INSTANCE = new Singleton1();

   //方式2:通過靜態(tài)代碼塊的方式,效果和方法1一樣
//    private static final Singleton1 INSTANCE;
//
//    static {
//        INSTANCE = new Singleton1();
//    }

   /**
    * 私有的構(gòu)造方法辽聊,防止產(chǎn)生多個(gè)對(duì)象
    */
   private Singleton1() {
   }

   /**
    * 通過該方法獲得實(shí)例
    *
    * @return
    */
   public static Singleton1 getInstance() {
       return INSTANCE;
   }

   public void doSomething() {

   }
}

可通過如下方式纪挎,在多個(gè)線程中創(chuàng)建多個(gè)單例對(duì)象,查看創(chuàng)建的對(duì)象hashCode是否相同判斷是否為單例

Executor executor = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    //測(cè)試餓漢式單例
                    Singleton1 singleton1 = Singleton1.getInstance();
                    Singleton1 singleton2 = Singleton1.getInstance();
                    System.out.println(singleton1.hashCode() + "\t-----\t" + singleton2.hashCode());
                }
            });
        }

打印結(jié)果如下身隐,不同線程下的Singleton1對(duì)象都是同一個(gè)HashCode,表示是全局單例

2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061

2廷区、懶漢式-線程不安全

  • 優(yōu)點(diǎn):做到了懶加載
  • 缺點(diǎn):多線程使用的時(shí)候會(huì)產(chǎn)生多個(gè)實(shí)例,實(shí)際開發(fā)中不要使用這種方案
public class SingLeton2 {
   private static SingLeton2 INSTANCE;

   private SingLeton2() {
   }

   public static SingLeton2 getInstance() {
       if (INSTANCE == null) {
           INSTANCE = new SingLeton2();
       }
       return INSTANCE;
   }
}

多線程創(chuàng)建此單例hashcode如下贾铝,存在hashCode不一致的問題,所有沒有做到全局單例

1337000531  -----   1337000531
1337000531  -----   1337000531
1337000531  -----   1337000531
1337000531  -----   1337000531
1337000531  -----   1337000531
1523178316  -----   1523178316
1337000531  -----   1337000531
1337000531  -----   1337000531
1337000531  -----   1337000531
1337000531  -----   1337000531

3埠帕、懶漢式 線程安全

  • 優(yōu)點(diǎn):加了同步垢揩,線程安全
  • 缺點(diǎn):效率太低,開發(fā)中不推薦使用這種寫法
public class Singleton3 {

   private static Singleton3 INSTANCE;

   private Singleton3() {
   }

   public static synchronized Singleton3 getINSTANCE() {
       if (INSTANCE == null) {
           INSTANCE = new Singleton3();
       }
       return INSTANCE;
   }
}

下面這種方式敛瓷,雖然加鎖了但是還是存在線程不安全的問題,同一時(shí)刻不同的線程走到if(instance==null)這一步時(shí)叁巨,還是會(huì)創(chuàng)建不同的對(duì)象

//方式二 線程不安全
   static class  Singleton7{
       private static Singleton7 instance;

       private Singleton7(){}

       public static Singleton7 getInstance() {
           if(instance==null){
               synchronized (Singleton7.class){
                   instance=new Singleton7();
               }
           }
           return instance;
       }
   }

4、雙重檢查

  • 優(yōu)點(diǎn):線程安全呐籽,延遲加載锋勺,效率高
  • 開發(fā)中推薦使用這種方案
public class Singleton4 {
  private static volatile Singleton4 instance;

  private Singleton4() {
  }

  public static Singleton4 getInstance() {
      if (instance == null) {
          synchronized (Singleton4.class) {
              if (instance == null) {
                  instance = new Singleton4();
              }
          }
      }
      return instance;
  }
}

5、靜態(tài)內(nèi)部類

  • 優(yōu)點(diǎn):線程安全狡蝶,也做到了懶加載庶橱,開發(fā)中推薦使用
public class Singleton5 {
   private Singleton5() {
   }

   private static class Singleton5Instance {
       private static final Singleton5 INSTANCE = new Singleton5();
   }

   public static Singleton5 getInstance() {
       return Singleton5Instance.INSTANCE;
   }
}

6、枚舉方式創(chuàng)建單例

  • <<Effective Java>>推薦使用這種方式創(chuàng)建單例贪惹,項(xiàng)目中推薦使用
public enum Singleton6 {
   INSTANCE;

   public void doSomething() {
       System.out.println("枚舉創(chuàng)建");
   }

   private String name;

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末苏章,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子奏瞬,更是在濱河造成了極大的恐慌枫绅,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件硼端,死亡現(xiàn)場(chǎng)離奇詭異并淋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)珍昨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門县耽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來句喷,“玉大人,你說我怎么就攤上這事酬诀≡嗳拢” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵瞒御,是天一觀的道長(zhǎng)父叙。 經(jīng)常有香客問我,道長(zhǎng)肴裙,這世上最難降的妖魔是什么趾唱? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蜻懦,結(jié)果婚禮上甜癞,老公的妹妹穿的比我還像新娘。我一直安慰自己宛乃,他們只是感情好悠咱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著征炼,像睡著了一般析既。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谆奥,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天眼坏,我揣著相機(jī)與錄音,去河邊找鬼酸些。 笑死宰译,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的魄懂。 我是一名探鬼主播沿侈,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼逢渔!你這毒婦竟也來了肋坚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤肃廓,失蹤者是張志新(化名)和其女友劉穎智厌,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盲赊,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡铣鹏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哀蘑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诚卸。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡葵第,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出合溺,到底是詐尸還是另有隱情卒密,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布棠赛,位于F島的核電站哮奇,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏睛约。R本人自食惡果不足惜鼎俘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辩涝。 院中可真熱鬧贸伐,春花似錦、人聲如沸怔揩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽商膊。三九已至歌逢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間翘狱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工砰苍, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留潦匈,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓赚导,卻偏偏與公主長(zhǎng)得像茬缩,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吼旧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353