1. 程式人生 > >JAVA設計模式---單例模式篇

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 }

&n