<tbody id="fuft6"><noscript id="fuft6"><video id="fuft6"></video></noscript></tbody>
    <tbody id="fuft6"><noscript id="fuft6"></noscript></tbody>
    <em id="fuft6"><acronym id="fuft6"></acronym></em>
          <button id="fuft6"><acronym id="fuft6"><u id="fuft6"></u></acronym></button>
          首頁技術文章正文

          線程安全單例有哪些?

          更新時間:2021-09-30 來源:黑馬程序員 瀏覽量:

          單例模式有很多實現方法,餓漢、懶漢、靜態內部類、枚舉類,試分析每種實現下獲取單例對象(即調用getInstance)時的線程安全,并思考注釋中的問題。

          餓漢式:類加載就會導致該單實例對象被創建

          懶漢式:類加載不會導致該單實例對象被創建,而是首次使用該對象時才會創建

          1632986290784_安全單利.png

          1. 餓漢單例

          // 問題1:為什么加 final
          // 問題2:如果實現了序列化接口, 還要做什么來防止反序列化破壞單例
          public final class Singleton implements Serializable {
              // 問題3:為什么設置為私有? 是否能防止反射創建新的實例?
              private Singleton() {}
              // 問題4:這樣初始化是否能保證單例對象創建時的線程安全?
              private static final Singleton INSTANCE = new Singleton();
              // 問題5:為什么提供靜態方法而不是直接將 INSTANCE 設置為 public, 說出你知道的理由
              public static Singleton getInstance() {
                  return INSTANCE;
              }
              public Object readResolve() {
                  return INSTANCE;
              }
          }


          2.枚舉單例

          // 問題1:枚舉單例是如何限制實例個數的
          // 問題2:枚舉單例在創建時是否有并發問題
          // 問題3:枚舉單例能否被反射破壞單例
          // 問題4:枚舉單例能否被反序列化破壞單例
          // 問題5:枚舉單例屬于懶漢式還是餓漢式
          // 問題6:枚舉單例如果希望加入一些單例創建時的初始化邏輯該如何做
          enum Singleton {
              INSTANCE;
          }


          3. 懶漢單例

          public final class Singleton {
              private Singleton() { }
              private static Singleton INSTANCE = null;
              // 分析這里的線程安全, 并說明有什么缺點
              public static synchronized Singleton getInstance() {
                  if( INSTANCE != null ){
                      return INSTANCE;
                  }
              INSTANCE = new Singleton();
              return INSTANCE;
              }
          }


          4. DCL 懶漢單例

          public final class Singleton {
              private Singleton() { }
              // 問題1:解釋為什么要加 volatile ?
              private static volatile Singleton INSTANCE = null;
              // 問題2:對比實現3, 說出這樣做的意義
              public static Singleton getInstance() {
                  if (INSTANCE != null) {
                      return INSTANCE;
                  }
                  synchronized (Singleton.class) {
                  // 問題3:為什么還要在這里加為空判斷, 之前不是判斷過了嗎
                      if (INSTANCE != null) { // t2
                          return INSTANCE;
                      }
                      INSTANCE = new Singleton();
                      return INSTANCE;
                  }
              }
          }


          5. 靜態內部類懶漢單例

          public final class Singleton {
              private Singleton() { }
              // 問題1:屬于懶漢式還是餓漢式
              private static class LazyHolder {
                  static final Singleton INSTANCE = new Singleton();
              }
              // 問題2:在創建時是否有并發問題
              public static Singleton getInstance() {
                  return LazyHolder.INSTANCE;
              }
          }

          IT培訓班


          猜你喜歡:

          Java如何處理高并發?Java高并發處理

          如何解決秒殺的高并發?

          Java并發編程:Callable、Future和FutureTask

          黑馬程序員JavaEE高手班

          在線咨詢 我要報名
          和我們在線交談!

          黄色网站片

          <tbody id="fuft6"><noscript id="fuft6"><video id="fuft6"></video></noscript></tbody>
            <tbody id="fuft6"><noscript id="fuft6"></noscript></tbody>
            <em id="fuft6"><acronym id="fuft6"></acronym></em>
                  <button id="fuft6"><acronym id="fuft6"><u id="fuft6"></u></acronym></button>