java設計模式----單例模式

        這個模式是很有意思,而且比較簡單,但是我還是要說因爲它使用的是如此的廣泛,如此的有人緣,單例就是單一、獨苗的意思,那什麼是獨一份呢?你的思維是獨一份,除此之外還有什麼不能山寨的呢?我們舉個比較難複製的對象:皇帝中國的歷史上很少出現兩個皇帝並存的時期,是有,但不多,那我們就認爲皇帝是個單例模式,在這個場景中,有皇帝,有大臣,大臣是天天要上朝參見皇帝的,今天參拜的皇帝應該和昨天、前天的一樣(過渡期的不考慮,別找茬哦),大臣磕完頭,擡頭一看,嗨,還是昨天那個皇帝,單例模式,絕對的單例模式,先看類圖:


然後我們看程序實現,先定一個皇帝:

package com.dashu.singleton;

/**
 * 一山不容二虎,皇帝只有一個 ,Emperor爲單例類
 * */
public class Emperor {
	private static Emperor emperor = null;

	private Emperor() {
	}

	public static Emperor getInstance() {
		if (emperor == null) {
			emperor = new Emperor();
		}
		return emperor;
	}

	public void emperorInfo() {
		System.out.println("我是唯一的皇帝");
	}
}

然後定義大臣:

package com.dashu.singleton;

/**
 * 大臣拜皇帝
 * 每天的皇帝都只有一個
 * */
public class Minister {
	public static void main(String[] args) {
		Emperor emperor1=Emperor.getInstance();//獲取皇帝實例
		emperor1.emperorInfo();
		
		Emperor emperor2=Emperor.getInstance();//獲取皇帝實例
		emperor2.emperorInfo();
	}
}
執行結果:


 這種設計風險:

           假如現在有兩個線程A和線程B,線程A執行到 this.singletonPattern =new SingletonPattern(),正在申請內存分配,可能需要 0.001 微秒,就在這 0.001 微秒之內,線程 B 執行到if(this.singletonPattern == null),你說這個時候這個判斷條件是true還是false?是true,那然後呢?線程B也往下走,於是乎就在內存中就有兩個SingletonPattern的實例了,看看是不是出問題了?如果你這個單例是去拿一個序列號或者創建一個信號資源的時候,會怎麼樣?業務邏輯混亂!數據一致性校驗失敗!最重要的是你從代碼上還看不出什麼問題,這纔是最要命的!因爲這種情況基本上你是重現不了的,不寒而慄吧,那怎麼修改?有很多種方案,我就說一種,能簡單的、徹底解決問題的方案:

public class SingletonPattern {
private static final SingletonPattern singletonPattern= new
SingletonPattern();
//限制住不能直接產生一個實例
private SingletonPattern(){
}
public synchronized static SingletonPattern getInstance(){
return singletonPattern;
}
}

直接 new 一個對象傳遞給類的成員變量 singletonpattern,你要的時候 getInstance()直接返回給你,解決問題!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章