須要頻繁的進行建立和銷燬的對象,建立對象時耗時過多或耗費資源過多安全
弊端:在類裝載的時候就完成實例化多線程
/** * 餓漢式單例 * * @author Wonder * @history create Wonder 2018年10月24日 上午9:55:32 * @version 1.0 */ public class Singleton1 { private Singleton1() { }// 1私有化構造 private final static Singleton1 singleton1 = new Singleton1();// 2實例化 public static Singleton1 getInstance() {// 3對外提供 return singleton1; } }
弊端:多線程環境下會產生多個single對象,線程不安全ide
/** * 懶漢式單例 * 多線程環境下會產生多個single對象 * * @author Wonder * @history create Wonder 2018年10月24日 上午10:17:59 * @version 1.0 */ public class Singleton2 { private Singleton2() { }// 1私有化構造 private static Singleton2 singleton2 = null;// 延遲實例 public static Singleton2 getInstance() { if (singleton2 == null) { singleton2 = new Singleton2(); } return singleton2; } }
弊端:效率低優化
同步方法的方式:獲取實例時,每次都要執行同步方法,效率過低spa
同步代碼塊的方式:可能多個線程同時進入if判斷,實際頁沒法起到線程同步的做用線程
/** * 懶漢式單例 只對須要鎖的代碼部分加鎖 * * @author Wonder * @history create Wonder 2018年10月24日 上午10:17:59 * @version 1.0 */ public class Singleton4 { private Singleton4() { }// 1私有化構造 private static Singleton4 single = null;// 延遲實例 public static Singleton4 getInstance() { if (single == null) { synchronized (Singleton4.class) { single = new Singleton4(); } } return single; } }
1.使用volatile關鍵字,防止防止 JVM
進行指令重排優化
3d
2.進行了兩次if (singleton == null)檢查,若是爲null,同步代碼塊,建立實例,不然直接返回singleton實例code
public class Singleton { private static volatile Singleton singleton; private Singleton() {} public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
靜態代碼塊的方式對象
public class Singleton5 { private Singleton5() { }// 1私有化構造 private static Singleton5 single = null;// 延遲實例 // static靜態代碼塊 static { single = new Singleton5(); } public static Singleton5 getInstance() { return single; } }
靜態內部類方式更優(懶加載)blog
靜態內部類方式在Singleton類被裝載時並不會當即實例化
public class Singleton { private Singleton() {} private static class SingletonInstance { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonInstance.INSTANCE; } }
簡單枚舉方式:
public enum Singleton { INSTANCE; public void whateverMethod() { } }
優化:內部枚舉類
public class SingletonFactory { // 內部枚舉類 private enum EnmuSingleton { SINGLETON; private Singleton6 single; // 枚舉類的構造方法在類加載是被實例化 private EnmuSingleton() { single = new Singleton6(); } public Singleton6 getInstance() { return single; } } public static Singleton6 getInstance() { return EnmuSingleton.SINGLETON.getInstance(); } } class Singleton6 { public Singleton6() { } }