【java】設計模式之單例模式

單例模式通常有兩種,餓漢單例和懶漢單例。


餓漢單例模式:

public class Singleton {

	private static Singleton singleton = new Singleton();

	private int flag;

	public int getFlag() {
		return flag;
	}

	public void setFlag(int flag) {
		this.flag = flag;
	}

	private Singleton() {

	}

	public static Singleton getInstance() {
		return singleton;
	}

懶漢單例模式

public class Singleton2 {
	private static Singleton2 singleton;

	private Singleton2(){
		
	}
	
	public static synchronized Singleton2 getInstance(){
	
		if(singleton == null){
			singleton = new Singleton2();
		}
		
		return singleton;
		
	}

餓漢單例模式中有一個 flag成員,以及相應的get和set方法。這不是單例模式必須的。方便後文做測試。

可以看到,它們都有一個共同點,那就是都有一個靜態的成員,且該成員就是自己。同樣,它們都有一個靜態方法,去返回自己的實例。

這樣做有什麼意思呢,根據我自身的體會,剛開始學的時候,會不明白,這個模式怎麼就能返回一個自己的實例,而且,在初始化實例的時候,對象本身有一個自己這個對象的方法,難道不會陷入死循環麼,自己實例化的成員對象,又實例化一個。

出現這樣的疑問,是自己基礎不牢固的問題。

其實是這樣的

	類定義中不能包含自己本身的對象,否則會引起像無限遞歸的問題,而靜態成員屬於類,而不屬於對象,靜態成員的作用域屬於類,但不佔類的大小,不屬於類的對象,內存在全局存儲區。

靜態成員是不屬於類的實例的,它是類的在編譯的時候初始化放在全局變量裏面的。

我們總是把類比喻成 一座大樓的圖紙,而實例對象就是建造出來的大樓。但是靜態成員是已經存在的東西,他不屬於當時實際建造出來的那個大樓,而是圖紙本身帶有的東西。


繼續


因爲已經類的成員是靜態的了,而且是私有的,所以,想要獲得這個靜態對象,就必須通過類的方法返回。所以我們需要一個可以 return Singleton類型的方法。

這就是實現單例模式的基本思路。

那麼懶漢和餓漢有什麼區別呢,其實看名字也能瞭解。


餓漢是不管你什麼時候用,我都在程序編譯的時候,就生成一個靜態對象放在全局變量區裏面(就好像餓了很久的人迫不及待地去做吃東西)

懶漢是你什麼時候用,我什麼時候給你實例一個對象,我不會在程序編譯的時候生成對象(就好像一個有拖延症的人,等到deadline來的時候纔會去做)


既然這樣,我們可以思考一個問題,餓漢因爲迫不及待的去做(編譯時就有了實例),所以當我們想要得到實例的時候,我們可以放心大膽的拿來用。

那麼在懶漢模式,我們怎麼知道有沒有已經生成的實例的呢?

可以輕而易舉地想到:加個if語句判斷一下,如果這個靜態成員爲null,那麼就實例化。

這樣做其實是會出現問題的:如果很多人在同時使用了這個方法,而此時靜態成員卻爲null,那麼系統會生成多於一個的靜態實例(事實上會報錯)。所以,我們

給方法加一個 synchronized,表示這個方法只能同時被一個線程使用。


一個簡單的測試方法:


public class testSingleton {
public static void main(String[] args){
Singleton s = Singleton.getInstance();
s.setFlag(3);
Singleton s1 = Singleton.getInstance();
System.out.println("s1的flag值爲"+s1.getFlag());
}


思路:既然返回同一個單例,那麼我在第一個引用中存入一個數值給一個變量,然後通過getInstance()給予第二個引用單例,在第二個引用中獲取這個變量,如果這個變量的數值和我存的一樣,那麼就證明這是同一個實例。


2015.11.6 補充:單例模式其實就是將聲明和實例化分開 ,讓類把類的實例化掌握在自己的手裏,至於調用者調用哪個實例,都是類自己說了算,所以可以在getInstance方法裏面添加各種限制。由此,我想到了生活中類似的場景:公司的員工需要用到各種辦公文具,一開始公司要求員工自己去買,買了之後拿發票報銷,採用單例模式之後,員工不再自己去買,而是去向公司申請,至於公司是給新的文具,還是舊的文具,都是公司自己說了算。


發佈了43 篇原創文章 · 獲贊 7 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章