java 單例模式的優化

1、

public class Singleton {

	private Singleton()
	{
		System.out.println("創建單例");
	}
	private static Singleton instance = new Singleton();
	public static Singleton getInstance()
	{
		return instance;
	}
	
	public static void otherStaticFunc()
	{
		System.out.println("其他方法");
	}
	public static void main(String[] args) {
		Singleton.otherStaticFunc();
	}
}
輸出:
創建單例
其他方法
不足分析:由於成員變量instance是static的,因此在JVM加載單例類時,就會被創建。此時就算調用該類中的其他方法,也會初始化instance,但是我們並沒有使用它。假如它的初始化要做的工作比較多,就會影響調用其他函數的速度。

因此引入延遲加載機制。

2、

public class LazySingleton {

	public LazySingleton() {
		System.out.println("延遲加載單例");
	}

	private static LazySingleton instance = null;
	public static synchronized LazySingleton getInstance()
	{
		if(instance == null)
			instance = new LazySingleton();
		return instance;
	}
	public static void otherStaticFunc()
	{
		System.out.println("其他方法");
	}
	public static void main(String[] args) {
		LazySingleton.otherStaticFunc();
	}
}
輸出:
其他方法
將instance初始化爲空,確保類加載時無額外負擔,getInstance()必須用同步關鍵字synchronized修飾,否者在多線程環境下會出問題。第二種方法較第一種方法相比,雖然實現了延遲加載的功能,但引入了同步,它的耗時遠遠大於第一種單例模式。

因此還要繼續改進。
3、

public class StaticSingleton {
	private StaticSingleton(){
		System.out.println("內部內維護單例");
	}
	private static class SingletonHolder{
		private static StaticSingleton instance = new StaticSingleton();
	}
	public static StaticSingleton getInstance(){
		return SingletonHolder.instance;
	}
	public static void otherStaticFunc()
	{
		System.out.println("其他方法");
	}
	public static void main(String[] args) {
		StaticSingleton.otherStaticFunc();
	}
}
輸出:
其他方法
用內部類的方式來維護單例,因爲在類加載時,其內部類不會被初始化,genInstance()被調用時纔會加載SingletonHolder。由於實例的建立是在類加載時完成,故對多線程是友好 的,不需要使用同步關鍵字。

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