1. 程式人生 > >Java設計模式菜鳥系列(六)單例模式建模與實現

Java設計模式菜鳥系列(六)單例模式建模與實現

單例模式(Singleton):是一種常用的設計模式。在Java應用中,單例物件能保證在一個JVM中,該物件只有一個例項存在。好處主要有:1、某些類建立比較頻繁,對於一些大型的物件,這是一筆很大的系統開銷。2、省去了new操作符,降低了系統記憶體的使用頻率,減輕GC壓力。

單例模式主要有兩種實現方式:1、懶漢式;2、餓漢式

一、uml建模


二、程式碼實現:

 1、懶漢式

/**
 * 示例:單例--單例物件能保證在一個JVM中,該物件只有一個例項存在。
 * 
 * 缺點:這種做法在多執行緒環境下,不安全
 * 
 * 懶漢式
 */

class Singleton {
	/**
	 * 持有私有靜態變數(也稱類變數),防止被引用
	 * 
	 * 此處賦值為null,目的是實現延遲載入 (因為有些類比較龐大,所以延遲載入有助於提升效能)
	 */
	private static Singleton instance = null;

	/** 私有構造方法,防止被例項化 */
	private Singleton() {

	}

	/** 靜態工廠方法,建立例項 --只不過這裡是建立自己,而且只能建立一個 */
	public static Singleton getInstance() {
		if (instance == null) {
			instance = new Singleton();
		}
		return instance;
	}

	public void info() {
		System.out.println("this is a test method...");
	}
}

/**
 * 客戶端測試類
 * 
 * @author Leo
 */
public class Test {
	public static void main(String[] args) {
		Singleton s1 = Singleton.getInstance();
		/**
		 * 呼叫普通方法
		 */
		s1.info();
		Singleton s2 = Singleton.getInstance();
		/**
		 * 執行結果為true,說明s1、s2這兩個類變數都指向記憶體中的同一個物件
		 */
		System.out.println(s1 == s2);
	}
}

2、餓漢式

/**
 * 餓漢式
 */

class Singleton {
	private static Singleton instance = new Singleton();

	private Singleton() {

	}

	public static Singleton getInstance() {
		return instance;
	}

	public void info() {
		System.out.println("this is a test method...");
	}
}

/**
 * 客戶端測試類
 * 
 * @author Leo
 */
public class Test {
	public static void main(String[] args) {
		Singleton s1 = Singleton.getInstance();
		/**
		 * 呼叫普通方法
		 */
		s1.info();
		Singleton s2 = Singleton.getInstance();
		/**
		 * 執行結果為true,說明s1、s2這兩個類變數都指向記憶體中的同一個物件
		 */
		System.out.println(s1 == s2);
	}

}

3、如果考慮多執行緒,那麼getInstance()方法要加同步synchronized,這時餓漢式比懶漢式要好,儘管資源利用率要差,但是不用同步。

/**
 * 
 * 考慮多執行緒的時候,下面這種做法可以參考一下:--懶漢式
 * 
 * 在建立類的時候進行同步,所以只要將建立和getInstance()分開,單獨為建立加synchronized關鍵字
 * 
 * 這種做法考慮效能的話,整個程式只需建立一次例項,所以效能也不會有什麼影響。
 * 
 * @author Leo
 */
public class SingletonTest {

	private static SingletonTest instance = null;

	private SingletonTest() {
	}

	private static synchronized void syncInit() {
		if (instance == null) {
			instance = new SingletonTest();
		}
	}

	public static SingletonTest getInstance() {
		if (instance == null) {
			syncInit();
		}
		return instance;
	}
}

三、總結

單例模式保證了一個類只有一個例項,且提供一個訪問全域性點的方式,更加靈活的保證了例項的建立和訪問約束。系統中只有一個例項,因此構造方法應該為私有 餓漢式:類載入時直接建立靜態例項;懶漢式:第一次需要時才建立一個例項,那麼getInstance方法要加同步 餓漢式比懶漢式要好,儘管資源利用率要差,但是不用同步。