單例餓漢式和飽漢式各自的有缺點(轉)


單例模式應用於一個類只有一個實例的情況,並且為其實例提供一個全局的訪問點。

特點

1.一個類只有一個實例

2.自己創建這個實例

3.整個系統只能用這個實例

應用場景

外部資源:每台計算機有若干個打印機,但只能有一個PrinterSpooler,以避免兩個打印作業同時輸出到打印機。

內部資源:大多數軟件都有一個(或多個)屬性文件存放系統配置,這樣的系統應該有一個對象管理這些屬性文件。

實現方式

1.餓漢式:單例實例在類裝載時就構建,急切初始化。(預先加載法)

/**
 * 餓漢式(推薦)
 *
 */
public class Singleton1 {

	private Singleton1() {
	}

	public static Singleton1 instance = new Singleton1();

	public Singleton1 getInstance() {
		return instance;
	}

}

 

優點 1.線程安全 
2.在類加載的同時已經創建好一個靜態對象,調用時反應速度快
缺點 資源效率不高,可能getInstance()永遠不會執行到,但執行該類的其他靜態方法或者加載了該類(class.forName),那么這個實例仍然初始化

 

2.懶漢式:單例實例在第一次被使用時構建,延遲初始化。

class Singleton2 {
	private Singleton2() {
	}

	public static Singleton2 instance = null;

	public static Singleton2 getInstance() {
		if (instance == null) {
              //多個線程判斷instance都為null時,在執行new操作時多線程會出現重復情況
			instance = new Singleton2();
		}
		return instance;
	}
}

 

懶漢式在單個線程中沒有問題,但在多線程就可能會出現兩個或多個Singleton2實例情況,

雖然后面實例化的Singleton2會覆蓋前面實例化的Singleton2,但最好避免這樣的情況。

改進方式就是加鎖synchornized

class Singleton3 {
	private Singleton3() {
	}

	public static Singleton3 instance = null;

	public static synchronized Singleton3 getInstance() {
		if (instance == null) {
			instance = new Singleton3();
		}
		return instance;
	}
}
優點 資源利用率高,不執行getInstance()就不會被實例,可以執行該類的其他靜態方法
缺點 第一次加載時不夠快,多線程使用不必要的同步開銷大


3.雙重檢測

class Singleton4 {
	private Singleton4() {
	}

	public static Singleton4 instance = null;

	public static Singleton4 getInstance() {
		if (instance == null) {
			synchronized (Singleton4.class) {
				if (instance == null) {
					instance = new Singleton4();
				}
			}
		}
		return instance;
	}
}

 

優點 資源利用率高,不執行getInstance()就不被實例,可以執行該類其他靜態方法
缺點 第一次加載時反應不快,由於java內存模型一些原因偶爾失敗

 

4.靜態內部類

class Singleton5 {
	private Singleton5() {
	}

	private static class SingletonHelp {
		static Singleton5 instance = new Singleton5();
	}

	public static Singleton5 getInstance() {
		return SingletonHelp.instance;
	}
}

 

優點 資源利用率高,不執行getInstance()不被實例,可以執行該類其他靜態方法
缺點 第一次加載時反應不夠快

 

總結:一般采用餓漢式(1),若對資源十分在意可以采用靜態內部類(4),不建議采用懶漢式及雙重檢測(2、3)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM