【設計模式】單例模式(Singleton Pattern)

  • 懶漢式
public class Singleton {
      private static Singleton instance;
      private Singleton() {};
      public static synchronized Singleton getInstance() {
            if (instance == null) {
                  instance = new Singleton();
            }
            return instance;
      }
}

首次調用時進行初始化;
synchronized加鎖保證線程安全;java

  • 餓漢式
public class Singleton {
      private static Singleton instance = new Singleton();
      private Singleton() {};
      public static Singleton getInstance() {
            return instance;
      }
}

類加載時就實例化,避免了多線程同步問題,不須要加鎖;安全

  • 雙重校驗鎖(DCL, double checked locking)
public class Singleton {
      private volatile static Singleton instance;
      private Singleton() {};
      public static Singleton getInstance() {
            if (instance == null){
                  synchronized (Singleton.class) {
                        if (instance == null){
                              instance = new Singleton();
                        }
                  }
            }
            return instance;
      }
}

首次調用時進行初始化;
volatile關鍵字保證了變量在多線程下的可見性以及防止指令重排;
經過加鎖和兩次校驗是否實例化避免多線程屢次建立實例的問題;如:
當實例未被建立時,線程t1調用getInstance方法,第一次判斷instance==null爲真,繼續執行,進入同步代碼塊。在t1建立實例以前,線程t2也調用了getInstance方法,而且因爲實例還未被建立,t2一樣能夠經過第一個if,繼續往下執行。t1建立完實例後退出同步代碼塊,t2進入,此時,若是沒有第二個if,那麼t2也會建立一個實例,可是加上第二個if,就能夠避免這個多線程屢次建立實例的問題。多線程

  • 靜態內部類
public class Singleton {
      private static class SingletonHolder {
            private static final Singleton INSTANCE = new Singleton();
      }
      private Singleton() {};
      public static final Singleton getInstance() {
            return SingletonHolder.INSTANCE;
      }
}

利用類加載機制避免多線程同步問題;
靜態內部類延遲了初始化,只有調用getInstance方法時纔會加載內部類,從而實例化;線程

相關文章
相關標籤/搜索