1. 程式人生 > >java單例模式.md

java單例模式.md

java單例模式

單例模式(Singleton Pattern)算是一個最簡單的設計模式了,單例模式屬於建立型模式,提供了一種建立物件的最佳方式。單例,顧名思義就是確保只有一個例項被建立。下面來說說我理解的一些思路。

通常我們建立例項物件都是通過new來建立,但是每次呼叫new都會建立不同的物件。這在單例模式肯定是不允許的,所以第一步,我們要將無參的建構函式私有化,對外斷了new的這條路,但是內部其實還是用new()來id建立物件的,只是這個物件是私有的。那這樣外面要如何來獲得這個物件呢?類裡面經常有private int age這類私有的成員變數,我們通常都是用get和set方法來訪問的,同樣,單例模式也是通過方法來獲得物件。好了,說了這麼多,還是來看看具體的程式碼。

簡單實現

public class Singleton {
 	//建立私有化例項物件
   private static Singleton instance = new Singleton();
   //建構函式私有化
   private Singleton(){}
 	//通過方法來獲得例項物件
   public static Singleton getInstance(){
      return instance;
   }
}

這麼一看單例模式程式碼還真少,其實也就三行(註釋的部分),當然還有一點前面忘了說,就是方法要宣告成static,不然外面根本沒辦法呼叫這個方法,因為無法用new來建立物件。既然方法是靜態方法,那成員變數也要加上static,宣告成類變數。一個簡單的單例模式就是這樣了,真的是太簡單了,當初我臨時抱佛腳,看了幾遍程式碼就覺得掌握了,結果過了一段時間這麼簡單的都記不得了,現在好好理解一下想忘掉估計都很難。

前面我一直都在說簡單單例模式的簡單實現,因為這東西對於不同的應用場景也有很多不一樣的要求。先說點簡單的,懶漢式和餓漢式。

懶漢式和餓漢式

其實前面寫的單例模式就是餓漢式,所以我想說說懶漢式,懶漢式理解了,餓漢式自然也就懂了。你可能聽過lazy-load懶載入,就是當這東西要用到的時候再去載入,懶漢式差不多就是這樣(這個例子不是很恰當,但是可以這麼理解)。和前面的程式碼相比就是修改一下而已。

public class Singleton {
 	//這裡沒有 = new Singleton(),也就是沒有建立物件
   private static Singleton instance;
   private
Singleton(){} public static Singleton getInstance(){ //物件如果已經建立過了就直接返回這個物件 if (instance == null) { instance = new Singleton(); } return instance; } } }

這個就是懶漢式的程式碼,可以和前面的餓漢式對照一下。這兩種方式都不是執行緒安全的,下面說一下執行緒安全的單例模式

雙檢鎖/雙重校驗鎖

(DCL,即 double-checked locking),就是在前面懶漢基礎上再加上一個null檢查。

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}

這裡volatile能夠提供可見性,在同步之前進行null檢查,儘量避免進入相對昂貴的同步塊,synchronized在class級別進行同步,保證執行緒安全的類方法呼叫。關於執行緒安全的單例模式還有很多實現方法,有需要的可以多去了解一下