java單例模式懶漢和餓漢

hndjknnjsnjd發表於2018-08-16

實現:

1 公開靜態的對外訪問方法

2 私有的構造方法(保證不被外部呼叫)

3 類載入時候建立物件

餓漢式:

public class Instance1 {

	// 餓漢式單例
	public static void main(String[] args) {

		Instance1 d1 = Instance1.getInstance1();
		Instance1 d2 = Instance1.getInstance1();

		if (d1 == d2 ) {
			System.out.println("====");
		}

	}

	private static Instance1 d = new Instance1();

	private Instance1() {
	}

	public static Instance1 getInstance1() {

		return d;
	}

}

懶漢式:

public class Instance2 {

	// 懶漢試
	public static void main(String[] args) {

		Instance2 d1 = Instance2.getInstance2();
		Instance2 d2 = Instance2.getInstance2();

		if (d1 == d2) {
			System.out.println("====");
		}

	}

	private static Instance2 d = null;

	private Instance2() {
	}

	public static Instance2 getInstance2() {
		 

		 

				if (d == null) {
					d = new Instance2();

			 
		}
		return d;
	}

}

 

懶漢式餓漢式有什麼區別:

餓漢式 在類載入的時候物件就已經new出來,對記憶體開銷比較大,不建議這樣使用。

 

懶漢式 單執行緒下執行緒安全,一定是單例模式。

在多執行緒下一定就是安全的嗎? 那可不一定?

ab兩個執行緒同時在d==null這行程式碼位置時,容易產生兩個物件,這樣子無法保證單例模式了,所以應該採用加鎖的方式進行同步。

	
	public static  synchronized  Instance2 getInstance2() {
		
		if(d == null) {
			d = new Instance2();
			
		}
		
		return d;
	}
	

以上程式碼,ab執行緒同時進入,必須等待一個執行緒釋放之後另一個執行緒才能進入鎖,這樣子程式碼不是很高效(如果有一個執行緒一直處於未釋放鎖,那另一個執行緒會一直處於等待狀態),所以採用雙重鎖進行判斷。

public class Instance2 {

	// 懶漢試
	public static void main(String[] args) {

		Instance2 d1 = Instance2.getInstance2();
		Instance2 d2 = Instance2.getInstance2();

		if (d1 == d2) {
			System.out.println("====");
		}

	}

	private static Instance2 d = null;

	private Instance2() {
	}

	public static Instance2 getInstance2() {
		if (d == null) {

			synchronized (Instance2.class) {

				if (d == null) {
					d = new Instance2();

				}

			}
		}
		return d;
	}

}

 

 

相關文章