溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java單例模式的4種實現方法

發布時間:2020-05-29 16:32:12 來源:億速云 閱讀:295 作者:鴿子 欄目:編程語言
單例模式的定義:
  • 單例模式,是一種常用的軟件設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中,應用該模式的類一個類只有一個實例。即一個類只有一個對象實例
單例模式的分類:
  • 立即加載/“餓漢模式”
    • 立即加載就是在使用類的時候已經將對象創建完畢
    • 立即加載在中文語義上有“著急”,“急迫”的含義,因此又稱為“餓漢模式”
    • 普通的立即加載:
      public class MyObject{
      private static MyObject mb = new MyObject();
      private MyObject(){}
      public static MyObject getInstance() {
          return mb;
      }
      }
  • 延遲加載/“懶漢模式”
    • 延遲加載是在調用getInstance()方法獲取實例對象時才創建對象
    • 延遲加載在中文語義上有“緩慢”,“不急迫”的含義,因此又稱為“懶漢模式”
    • 普通的延遲加載:
      public class MyObject{
      private static MyObject mb;
      private MyObject(){}
      public static MyObject getInstance() {
          if (mb == null)
              mb = new MyObject();
          return mb;
      }
      }
延遲加載/“懶漢模式”的缺點
  • 雖然上述的代碼可以實現單例設計模式,但是在多線程環境中,前面的延遲加載的代碼是完全錯誤的,根本不能實現保持單例的狀態。因為多線程環境中,會存在多個線程調用getInstance()方法的情況,由于線程安全的問題就會導致創建出多個實例
單例模式的幾種實現方法

1.使用DCL雙重檢查鎖機制實現

  • 雖然直接在方法上使用synchronized上鎖也能實現線程安全的單例,但是性能非常差,使用DCL機制后不僅線程安全還能使性能有所提升
  • 屬于延遲加載
  • 代碼:
    public class MyObject{
    private static MyObject mb;
    private MyObject(){}
    public static MyObject getInstance() {
        if (mb == null) {
            synchronized (MyObject.class) {
                if (mb == null) {
                    mb = new MyObject();
                }
            }
        }   
        return mb;
    }
    }

    2.使用靜態內置類實現單例模式

  • 靜態內部類和靜態屬性屬性會在類加載是時候執行,因此使用類的使用就將實例對象創建好了,屬于立即加載
  • 也因為只在類加載的時候加載一次并將對象創建完畢,因此線程是安全的
  • 代碼:
    public class MyObject{
    //內部類方式
    private static class MyObjectHandler {
        private static MyObject mb =  new MyObject();
    }
    private MyObject(){}
    public static MyObject getInstance() {
        return MyObjectHandler.mb;
    }
    }

    3.使用static代碼塊實現單例模式

  • 和使用靜態內部類的方式一樣,也是在類加載的時候將實例對象創建好了,所以線程也是安全的
  • 代碼:
    public class MyObject{
        private static MyObject mb = null;
        private MyObject(){}
        static {
            mb = new MyObject();
        }
        public static MyObject getInstance() {
            return mb;
        }
    }

    4.使用enum枚舉數據類型實現單例模式

  • 在使用枚舉類的時候構造方法會被自動調用,而且通過反射也無法獲取枚舉中的屬性和方法因此線程也是安全的
  • 代碼:
public enum MyEnum{
    connectionFactory;
    private Connection connection;
    //枚舉類的構造方法默認是private的,所以訪問限定符private可以省略不寫
    MyEnum {
        MysqlDataSource dataSource = new MysqlDataSource();
        dataSource.setURL();
        dataSource.setUser();
        dataSource.setPassword();
        connection = dataSource.getConnection();
    }
    public Connection getInstance() {
        return connection;
    }
}


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女