設計模式筆記——單例模式

前幾天校園招聘會,投簡歷時就直接給我來了一份筆試題。我一看,臥槽,全都是考很基本很基本的題,可以說基本到噁心,然而對於我這個實習了半年,可以獨自把一個項目完成的程序猿來說,很可惜這些基本題卻把我放倒了,真是諷刺啊。就感覺一個全棧工程師被問如何輸出一個helloworld被嚇得跪地直喊OMG一樣,哈哈,開個玩笑。沒辦法,面向學生招聘,企業都愛玩這一套,對於我這個有實戰經驗的人來說,儘管這些基本的東西感覺在實際項目還真不怎麼用得上,但還是得去沉澱一下啊。

筆試題的組成基本少不了數據結構和設計模式,既然你把我放倒了,那麼我就從設計模式開始補回來吧,堅持一天一種模式學習吧。

首先是設計模式裏最簡單的一種模式,單例模式。顧名思義,就是一個類,在使用的時候確保只有一個實例被初始化。

第一步,創建一個單例類:

SingleTon.java

public class SingleTon {

	private static SingleTon instance;
	
	private int count;
	
	//構造方法爲私有,無法直接new()獲得實例
	private SingleTon(){
		count=0;
	}
	
	public static SingleTon getInstance(){
		if(instance==null){
			instance=new SingleTon();
		}
		return instance;
	}
	
	public void print(){
		System.out.println(count);
	}
	
	public void add(){
		System.out.println("變量加1");
		count++;
	}
	
}


第二步,創建一個運行測試類:

PatternTest.java

public class PatternTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		SingleTon singleTon1=SingleTon.getInstance();
		singleTon1.print();
		singleTon1.add();
		
		SingleTon singleTon2=SingleTon.getInstance();
		singleTon2.print();
		
	}

}


運行結果:



果然很簡單吧,兩次獲取實例都是同一個實例,所以加一操作add()也只是在同一個對象上的成員變量加一。


不過,對於單例模式,若是比較起其性能,如內存,線程安全等,則有幾種不同的實現方式。

1.  節省內存(懶漢模式),非線程安全式:

public class SingleTon {

	private static SingleTon instance;
	
	//構造方法爲私有,無法直接new()獲得實例
	private SingleTon(){}
	
	public static SingleTon getInstance(){
		if(instance==null){
			instance=new SingleTon();
		}
		
		return instance;
	}
	
	
}
實際上就和上面一開始的代碼一樣,只有使用時才實例化,但沒有考慮到線程安全。


2. 節省內存, 線程安全,效率慢式:

public class SingleTon {

	private static SingleTon instance;
	
	//構造方法爲私有,無法直接new()獲得實例
	private SingleTon(){}
	
	public static synchronized SingleTon getInstance(){
		if(instance==null){
			instance=new SingleTon();
		}
		
		return instance;
	}
	
	
}
就是在getInstance()方法里加個同步鎖而已,雖然可以達到線程安全,但效率慢。


3. 耗內存,線程安全,效率快式:

public class SingleTon {

	private static SingleTon instance=new SingleTon();
	
	//構造方法爲私有,無法直接new()獲得實例
	private SingleTon(){}
	
	public static SingleTon getInstance(){
		return instance;
	}
	
	
}
就直接在加載類的時候就初始化了,這樣會耗內存,但不使用synchronize鎖,這樣就可以不用加同步鎖也可以達到線程安全的效果。


實際上還有其他的方式,但一般都是使用第三種方式創建單例多。






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