單件模式多線程環境下實現

 參考《Head First 設計模式》

單件模式 定義:確保一個類只有一個實例,並提供一個全局的訪問點。

 

單件模式如果沒有做同步處理,在多線程環境下很容易造成出現多個實例情況。一下三種實現方式可以解決這個問題。

實現一:

 

public class Singleton {
	private static Singleton uniqueInstance;
	// other useful instance variables here
	private Singleton() {}
	public static synchronized Singleton getInstance() {
		if (uniqueInstance == null) {
			uniqueInstance = new Singleton();
		}
		return uniqueInstance;
	}
	// other useful methods here
}

 

 此方法是好理解的一種,但是有個缺陷,在每次調用getInstance()方法都需要進行代碼同步,所以代碼執行效率會有所降低。還有單例模式在創建實例後就不需要進行同步處理了,如果在調用程序頻繁且對性能要求較高的地方儘量少使用此方法。

 

實現二(急切創建實例):

 

public class Singleton {
	private static Singleton uniqueInstance = new Singleton();
 
	private Singleton() {}
 
	public static Singleton getInstance() {
		return uniqueInstance;
	}
}

 利用這種做法,JVM在加載這個類是就馬上創建此唯一的單件實例。JVM保證在任何線程訪問uniqueInstance變量之前,一定先創建此實例。在靜態初始化器中創建單件,保證了線程安全

如果程序總是創建並使用單件實例,或者在創建和運行時方面的負擔不太繁重,可以考慮此方法。

 

 實現三(雙重檢查加鎖):

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

 

 首先檢查是否創建實例了,如果未創建才進行同步。這樣一來,只有第一次纔會進行同步。第一次執行時。進入同步代碼塊後在檢查一次,這樣做確保多個線程執行時,創建唯一實例。如果仍是null,才創建實例。

注意此處用到volatile 修飾符,確保變量uniqueInstance被初始化成Singleton實例時,多個線程立即可見

。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章