Java設計模式----單例模式

單例設計模式所解決的問題就是:保證類的對象在內存中唯一。

1、餓漢

/**
 * @說明:餓漢模式
 * 解決思路:
 *	1.不允許其他程序使用new創建該類對象。(別人new不可控)
 *	2.在該類中創建一個本類實例。
 *	3.對外提供一個方法讓其他程序可以獲取該對象。
 * 步驟:
 *  1.私有化該類的構造函數
 *  2.通過new在本類中創建一個本類對象。
 *  3.定義一個共有的方法將創建的對象返回。
 * @author heyanpeng
 */
public class Single {
	
	private final static Single sigle = new Single();
	
	// 私有化構造函數
	private Single () {
		
	}
	
	public static Single getInstance(){
		return sigle;
	}
}

2、懶漢

/**
 * @說明:懶漢模式
 * 	延遲對象創建,第一次使用的時候創建,節省了內存空間
 * 	存在的弊端:多線程編程中,使用懶漢式可能會造成類的對象在內存中不唯一
 *  
 * @author heyanpeng
 */
public class Single2 {

	private static Single2 single2 = null;
	
	// 私有化構造函數
	private Single2(){
		
	}
	
	public static Single2 getInstance(){
		if (null == single2) {
			single2 = new Single2();
		}
		return single2;
	}
}

總結:
懶漢式在面試的時候經常會被提到,因爲知識點比較多,而且還可以和多線程結合起來綜合考量。
餓漢式在實際開發中使用的比較多。

3、懶漢式多線程優化

/**
 * @說明:懶漢多線程優化
 * 	在懶漢模式下,if(null == single2) 的判斷存在線程安全
 *  
 * @author heyanpeng
 */
public class Single3 {
	
	private static Single3 single3 = null;
	
	// 私有化構造函數
	private Single3(){
			
	}
	
	/**
	 * 方案1: 方法增加synchronized同步
	 */
	public static synchronized  Single3 getInstance(){
		if (null == single3) {
			single3 = new Single3();
		}
		return single3;
	}
	
	/**
	 * 方案2: 代碼塊增加synchronized同步
	 */
	public static  Single3 getInstance2(){
		synchronized(Single3.class){
			if (null == single3) {
				single3 = new Single3();
			}
			return single3;
		}
	}
	
	/**
	 * 方案3: 爲空的時候加synchronized同步,再進行爲空判斷
	 */
	public static  Single3 getInstance3(){
		if (null == single3) {
			synchronized(Single3.class){
				if (null == single3) {
					single3 = new Single3();
				}
			}
		}
		return single3;
	}
}

總結:假設我們現在並沒有創建單例對象,即snull,那麼我們調用getInstance方法的時候,會進入if塊,然後進入同步代碼塊,此時,別的線程如果想要創建Single實例,就必須獲取鎖;等當前線程創建完實例對象,釋放鎖之後,假設正巧有幾個線程已經進入了if塊中,它們會拿到鎖,進入同步代碼塊,但是由於進行了判空操作,所以不會創建Single實例,而是直接返回已經創建好的Single實例。如果有多個其他線程進入了if塊,當它們依次進入同步代碼塊的時候,同理也不會創建新的Single實例。而沒有進入if塊的線程,判空操作之後不滿足條件,進不了if塊,而直接執行了下一條語句return s;其後的線程調用getInstance方法時,只會判斷一次snull,不滿足條件直接返回Single單例s,這樣就大大提高了了執行效率。
第一行代碼是第一次判空操作,目的是提高效率;第三行代碼是同步代碼塊的入口,目的是保證線程安全;第五行代碼進行第二次判空操作是爲了保證單例對象的唯一性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章