單例模式(singleton):是JAVA中最簡單的一種設計模式,屬於創建型模式。所謂單例,就是整個程式有且僅有一個實例。 特點: 構造方法私有化 在本類中實例化一個對象作為本類的屬性 對外提供一個訪問本類對象的方法 餓漢式:類載入時就載入對象 應用場景:小對象,頻繁用,高併發 特點:線程安全,比較 ...
單例模式(singleton):是JAVA中最簡單的一種設計模式,屬於創建型模式。所謂單例,就是整個程式有且僅有一個實例。
特點:
構造方法私有化
在本類中實例化一個對象作為本類的屬性
對外提供一個訪問本類對象的方法
餓漢式:類載入時就載入對象
應用場景:小對象,頻繁用,高併發
特點:線程安全,比較常用,但容易產生垃圾,影響性能,因為一開始就初始化。
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 }
懶漢式:對象何時需要何時創建,線程不安全
應用場景:單線程,大對象
特點:線程不安全,延遲初始化。
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 }