使用前提:
需要頻繁的進行創建和銷毀的對象,創建對象時耗時過多或耗費資源過多
三要素:
- 1、構造方法私有化;
- 2、實例化的變量引用私有化;
- 3、獲取實例的方法共有。
1.餓漢式單例
弊端:在類裝載的時候就完成實例化

/** * 餓漢式單例 * * @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; } }
2.懶漢式單例
弊端:多線程環境下會產生多個single對象,線程不安全

/** * 懶漢式單例 * 多線程環境下會產生多個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; } }
3.懶漢式單例(synchronized同步鎖)
弊端:效率低
同步方法的方式:獲取實例時,每次都要執行同步方法,效率太低
同步代碼塊的方式:可能多個線程同時進入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; } }
4.雙重檢查
1.使用volatile關鍵字,防止防止 JVM
進行指令重排優化
2.進行了兩次if (singleton == null)檢查,如果為null,同步代碼塊,創建實例,否則直接返回singleton實例

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; } }
5.靜態代碼塊和靜態內部類
靜態代碼塊的方式

public class Singleton5 { private Singleton5() { }// 1私有化構造 private static Singleton5 single = null;// 延遲實例 // static靜態代碼塊 static { single = new Singleton5(); } public static Singleton5 getInstance() { return single; } }
靜態內部類方式更優(懶加載)
靜態內部類方式在Singleton類被裝載時並不會立即實例化

public class Singleton { private Singleton() {} private static class SingletonInstance { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonInstance.INSTANCE; } }
6.枚舉實現
簡單枚舉方式:

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() { } }