單例模式(singleton):是JAVA中最簡單的一種設計模式,屬於建立型模式。所謂單例,就是整個程序有且僅有一個實例。設計模式
特色:安全
構造方法私有化多線程
在本類中實例化一個對象做爲本類的屬性併發
對外提供一個訪問本類對象的方法高併發
餓漢式:類加載時就加載對象性能
應用場景:小對象,頻繁用,高併發spa
特色:線程安全,比較經常使用,但容易產生垃圾,影響性能,由於一開始就初始化。線程
1 class Singleton{ 2 //構造方法私有化 3 private Singleton() { 4 System.out.println("構造方法"); 5 } 6 //對象在類加載時初始化 7 private static final Singleton instance = new Singleton(); 8 //提供對外的訪問方法 9 public static Singleton getInstance() { 10 return instance; 11 } 12 }
懶漢式:對象什麼時候須要什麼時候建立,線程不安全設計
應用場景:單線程,大對象code
特色:線程不安全,延遲初始化。
1 class Singleton{ 2 private Singleton() { 3 System.out.println("構造方法"); 4 } 5 private static Singleton instance; 6 public static Singleton getInstance() { 7 if (instance == null) { 8 instance = new Singleton(); 9 } 10 return instance; 11 } 12 }
同步鎖機制
應用場景:多線程,大對象,稀少用。
特色:經過加鎖保證了線程安全,性能會降低。
1 class Singleton{ 2 private Singleton() { 3 System.out.println("構造方法"); 4 } 5 private static Singleton instance; 6 //同步方法,線程安全,但性能會降低 7 public static synchronized Singleton getInstance() { 8 if (instance == null) { 9 instance = new Singleton(); 10 } 11 return instance; 12 } 13 }
雙重驗證機制
應用場景:大對象,稀少用,併發量不能太大
特色:線程安全,延遲初始化。
1 class Singleton{ 2 private Singleton() { 3 System.out.println("構造方法"); 4 } 5 private static volatile Singleton instance; 6 //同步方法,雙重驗證,減小阻塞次數,提升性能 7 public static Singleton getInstance() { 8 if (instance == null) { 9 synchronized (Singleton.class) { 10 if (instance == null) { 11 instance = new Singleton(); 12 } 13 } 14 } 15 return instance; 16 } 17 }
靜態內部類
引用場景:大對象,頻繁用,高併發
特色:延時對象建立,減小資源佔用,提升系統性能
1 class Singleton{ 2 private Singleton() { 3 System.out.println("構造方法"); 4 } 5 static class Inner{ 6 private static final Singleton instance = new Singleton(); 7 } 8 public static Singleton getInstance() { 9 return Inner.instance; 10 } 11 }
枚舉
1 enum Singleton{ 2 //類加載時建立 3 INSTANCE; 4 }
因爲單例模式是建立型模式,每次調用都會新建一個實例。那麼一個重要的問題就是反序列化。當實例被寫入到文件到反序列化成實例時,咱們須要重寫readResolve
方法,以讓實例惟一。
1 private Object readResolve() throws ObjectStreamException{ 2 return singleton; 3 }