1. 程式人生 > >設計模式-建立型:單例模式(2)

設計模式-建立型:單例模式(2)

上篇我們學習了最簡單的單例模式,但在有些應用下,我們希望只有在使用到該類的時候才去建立例項,而不是在類載入的時候。

下面我們看到的單例模式實現在多執行緒併發情況下是不安全的。

public class SingletonUnSafe {

	private static SingletonUnSafe instance;

	private SingletonUnSafe() {

	}

	public static SingletonUnSafe getInstance() {
		if (null == instance) {
			instance = new SingletonUnSafe();
		}
		return instance;
	}

}

多執行緒併發情況下,程式在執行

if (null == instance)
{
	instance = new SingletonUnSafe();
}
由於CPU對多執行緒執行策略,會產生多個例項。為了避免這樣的問題,我們可以將 getInstance()方法宣告為 synchronized

public class SingletonUnSafe {

	private static SingletonUnSafe instance;

	private SingletonUnSafe() {

	}

	public static synchronized SingletonUnSafe getInstance() {
		if (null == instance) {
			instance = new SingletonUnSafe();
		}
		return instance;
	}

}
對整個方法宣告 synchronized,在多執行緒併發情況下對效能會有影響,所以我們使用synchronized程式碼塊來實現

public class SingletonThreadSafe {

	private volatile static SingletonThreadSafe instance;

	private SingletonThreadSafe() {
		
	}

	public static SingletonThreadSafe getInstance() {
		if (null == instance) {
			synchronized (SingletonThreadSafe.class) {
				if (null == instance) {
					instance = new SingletonThreadSafe();
				}
			}
		}
		return instance;
	}
}
大家會注意到程式碼
if (null == instance){
	synchronized (SingletonThreadSafe.class) {
	    if (null == instance) {
		    instance = new SingletonThreadSafe();
	    }
	}
}
這裡的雙重判斷可以使程式在建立了例項後,避免每次都執行 synchronized程式碼塊。

現在我們已經完成了執行緒安全的單例模式。