1. 程式人生 > >關於單例設計模式中的雙重判斷的理解和分析

關於單例設計模式中的雙重判斷的理解和分析

之前在很多地方看到過這種單例的實現,但是對其中的兩個if判斷的作用不理解。今天就詳細的解釋一下:

class SingletonTwo{	
	/* 持有私有靜態例項,防止被引用,此處賦值為null,目的是實現延遲載入 */ 
	private static SingletonTwo instance = null;	
	/* 私有構造方法,防止被例項化 */
	private SingletonTwo(){
		
	}
	
	public static SingletonTwo getInstance() {  
	//位置1
        if (instance == null) {  
            //位置2
            synchronized (instance) {  
            	//位置3
                if (instance == null) {  
                    //位置4
                    instance = new SingletonTwo();  
                }  
            }  
        }  
        return instance;  
    }  
}



假設執行緒A和B作為第一批呼叫者同時或幾乎同時呼叫靜態工廠方法getInstance。

1)因為A和B是第一批呼叫者,當它們進入靜態工廠方法時,instance變數是null。因此它們幾乎同時到達 位置2。

2)  假設A執行緒先進入 synchronized (instance),到達位置3,這時由於同步機制,執行緒B無法到達位置3,只能在位置2等待。

3)執行緒A執行instance = new SingletonTwo()語句,使得instance引用指向一個物件。此時執行緒B還在位置2上等待。

4)執行緒A退出synchronized (instance),返回SingletonTwo物件,退出靜態工廠方法。

5)執行緒B進入 synchronized (instance)塊,達到位置3,此時instance已經不為null,因此執行緒B退出synchronized (instance),

     返回SingletonTwo物件(執行緒A所建立的SingletonTwo物件),退出靜態工廠方法。

到此為止,執行緒A和B得到同一個SingletonTwo物件。

第一個if判斷的作用:是為了提高程式的 效率,當SingletonTwo物件被建立以後,再獲取SingletonTwo物件時就不用去驗證同步程式碼塊的鎖及後面的程式碼,直接返回SingletonTwo物件

第二個if判斷的作用:是為了解決多執行緒下的安全性問題,也就是保證物件的唯一。如果沒有第二個if判斷,在上面介紹的步驟5處,執行緒B進入synchronized (instance)塊,不用去驗證instance是否為null,就會直接建立一個SingletonTwo新物件,這樣整個程式執行下來就有可能建立多個例項。