單例模式的實(shí)現(xiàn)方式

最近看到組里有人實(shí)現(xiàn)單例模式喝滞,采用靜態(tài)內(nèi)部類的方式诫欠,不是很懂這種寫法的優(yōu)點(diǎn),查了一下各種寫法的優(yōu)缺點(diǎn)佣谐,總結(jié)一下。
內(nèi)容多處參考文章:http://wuchong.me/blog/2014/08/28/how-to-correctly-write-singleton-pattern/

懶漢式

public class Single {

      private static Single mInstance;
      private Single(){}

      // 線程不安全
      public static Single getInstance() {
          if (mInstance == null) {
              mInstance = new Single();
          }
          return mInstance;
      }

      // 線程安全方妖,效率低狭魂,只有一個線程能調(diào)用getInstance()方法。
      public static synchronized Single getInstance() {
          if (mInstance == null) {
              mInstance = new Single();
          }
          return mInstance;
      }

      // 同步代碼塊加鎖吁断,雙重檢查鎖趁蕊。
      public static Single getInstance() {
          if (mInstance == null) {  //Single Checked 
              synchronized (Single.class) {
                  if (mInstance == null) { //Double Checked 
                      mInstance = new Single(); 
                  } 
              } 
          } 
          return mInstance ;
      }
}

同步代碼塊加鎖,雙重檢查

  • 這個是平時最常用的方式仔役,看似完美掷伙,其實(shí)是有問題的。
    因?yàn)?code>mInstance = new Single();這句語句的執(zhí)行又兵,不是一個原子操作任柜,JVM在執(zhí)行這條語句時,做了3個操作沛厨。
  1. 給mInstance分配內(nèi)存宙地。
  2. 調(diào)用Single的構(gòu)造方法進(jìn)行初始化。
  3. 將mInstance對象指向分配的內(nèi)存空間(執(zhí)行完這步mInstance就非空啦)逆皮。

但是在 JVM 的即時編譯器中存在指令重排序的優(yōu)化宅粥。也就是說上面的第二步和第三步的順序是不能保證的,最終的執(zhí)行順序可能是 1-2-3 也可能是 1-3-2电谣。如果是后者秽梅,則在 3 執(zhí)行完畢、2 未執(zhí)行之前剿牺,被線程二搶占了企垦,這時 instance 已經(jīng)是非 null 了(但卻沒有初始化),所以線程二會直接返回 instance晒来,然后使用钞诡,然后順理成章地報錯。

餓漢式

public class Single {
      // 類加載時就被初始化,線程安全
      private static final Single mInstance = new Single();
      private Single(){}

      public static Single getInstance() {
          return mInstance;
      }
}

缺點(diǎn)

  • 不是懶加載模式荧降,類被加載時就被初始化接箫。
  • 如果構(gòu)造函數(shù)需要傳遞參數(shù)時,不能滿足誊抛。

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

public class Single {

      private Single(){}

      private static class InnerHolder {
            private static final INSTANCE = new Single();
      }

      public static Single getInstance() {
            return InnerHolder.INSTANCE;
      }
}

這種寫法仍然使用JVM本身機(jī)制保證了線程安全問題列牺;由于 InnerHolder 是私有的,除了 getInstance() 之外沒有辦法訪問它拗窃,因此它是懶漢式的;同時讀取實(shí)例的時候不會進(jìn)行同步泌辫,沒有性能缺陷随夸;也不依賴 JDK 版本。

總結(jié)

單例模式最好采用靜態(tài)內(nèi)部類實(shí)現(xiàn)震放,但是如果對懶加載參數(shù)沒有要求宾毒,餓漢式也可以。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末殿遂,一起剝皮案震驚了整個濱河市诈铛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌墨礁,老刑警劉巖幢竹,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異恩静,居然都是意外死亡焕毫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門驶乾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邑飒,“玉大人,你說我怎么就攤上這事级乐「硐蹋” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵风科,是天一觀的道長撒轮。 經(jīng)常有香客問我,道長丐重,這世上最難降的妖魔是什么腔召? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮扮惦,結(jié)果婚禮上臀蛛,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好浊仆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布客峭。 她就那樣靜靜地躺著,像睡著了一般抡柿。 火紅的嫁衣襯著肌膚如雪舔琅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天洲劣,我揣著相機(jī)與錄音备蚓,去河邊找鬼。 笑死囱稽,一個胖子當(dāng)著我的面吹牛郊尝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播战惊,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼流昏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吞获?” 一聲冷哼從身側(cè)響起况凉,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎各拷,沒想到半個月后刁绒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡撤逢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年膛锭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚊荣。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡初狰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出互例,到底是詐尸還是另有隱情奢入,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布媳叨,位于F島的核電站腥光,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏糊秆。R本人自食惡果不足惜武福,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望痘番。 院中可真熱鬧捉片,春花似錦平痰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至莹规,卻和暖如春赔蒲,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背良漱。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工舞虱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人母市。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓砾嫉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親窒篱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

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