1. 程式人生 > >單例模式之懶漢模式(延遲載入)

單例模式之懶漢模式(延遲載入)

什麼是延遲載入?延遲載入就是在呼叫get()方法時候建立,常見的方法就是在

get()中例項化。

看實現程式碼:

package test;

public class MyObject {

	private static MyObject myObject;

	private MyObject() {
	}

	public static MyObject getInstance() {
		// 延遲載入
		if (myObject != null) {
		} else {
			myObject = new MyObject();
		}
		return myObject;
	}

}

但是,這樣方式的延遲載入,在多執行緒的環境中,就會出現錯誤,很嚴重的錯誤。根本不能保證單例模式的實現。

因為在getInstance中,如果有多個執行緒同時計入getInstance,那麼就有可能new出多個MyObject。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

懶漢模式出現問題的解決方法:

①:將getInstance用synchronized修飾。

②:在getInstance方法中利用synchronized同步塊或者lock進行同步。

③:使用DCL雙檢查機制。

針對第三種方法,看一段程式碼:

package test;

public class MyObject {

	private volatile static MyObject myObject;

	private MyObject() {
	}

	// 使用雙檢測機制來解決問題
	// 即保證了不需要同步程式碼的非同步
	// 又保證了單例的效果
	public static MyObject getInstance() {
		try {
			if (myObject != null) {
			} else {
				// 模擬在建立物件之前做一些準備性的工作
				Thread.sleep(3000);
				synchronized (MyObject.class) {
					if (myObject == null) {
						myObject = new MyObject();
					}
				}
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return myObject;
	}
	// 此版本的程式碼稱為:
	// 雙重檢查Double-Check Locking

}

如有哪疏漏,還請指出,共同學習!