分析設計單例模式的幾種方法以及單例模式的優點

1.爲什麼要用單例模式?

 (1)對於頻繁使用的對象,可以省略對象創建時所消耗的時間。尤其是對重量級系統而言是一個非常可觀的系統開銷。

 (2)由於new對象的次數變小,系統的內粗消耗也會降低,可以減輕gc的壓力,縮短gc停頓時間。

2.設計單例模式的幾種方法

(1)簡單的單例模式

public class Singleton {
	private Singleton() {
		System.out.println("Singleton is  created");
	}
	private static Singleton instance = new Singleton();
	public static Singleton getInstance() {
		return instance;
	}
}

這種設計單例模式的方法雖然簡單,但是無法對instance對象做延遲加載,因爲instance是static修飾的,所以當jvm加載類的時候就會常見instance對象,如果此時單例類中還有其他方法,在任何使用該單例類的時候就是加載instance對象,而不管instance方法是否被用到。

(2)懶加載及實現線程安全的單例模式

/**
 * @author 江鵬飛
 * 單例對象的延遲加載及線程安全實現
 */
public class LazySingleton {
	private LazySingleton(){
		System.out.println("lazySingleton is created!");
	}
	private static LazySingleton singleton = null;
	public static synchronized LazySingleton getLazySingleton(){
		if(singleton==null){
			singleton = new LazySingleton();
		}
		return singleton;
	}
}

這種方法解決了(1)中的延遲加載問題以及保證了線程安全(因爲在不同線程調用getLazySingleton()時在一個線程創建對象前,另外一個線程調用的時候會誤認爲當前instance爲空),這種方法雖然解決了上述問題,但是如果在代碼中使用synchronized時在多線程環境會出現線程阻塞影響系統效率。顯然這個也不是一個很好的實際方法。

(3)使用內部類的方式設計單例模式(推薦)

/**
 * @author 江鵬飛
 *	使用內部類的方式實現單例模式
 */
public class StaticSingleton {
	private StaticSingleton(){
		System.out.println("StaticSingleton is created!");	
	}
	private static class SingletonHolder{
		private static StaticSingleton instance = new StaticSingleton(); 
	}
	public static StaticSingleton getInstance(){
		return SingletonHolder.instance;
	}
}

這種方法解決了(2)中多線程環境下線程阻塞問題提高了系統的性能,使用內部類來維護單例的實例,當StaticSingleton 被加載時它的內部類並不會初始化。當StaticSingleton 被jvm加載時單例類SingletonHolder不會被初始化,而當調用 getInstance()方法時內部類纔會被jvm加載從而初始化instance,因爲實例對象的創建在類加載時完成,則天生對線程友好。getInstance()也不需要synchronize修飾。這實現方式同時具備以上兩種實現的優點。

注意: 通常情況下用上面設計的單例方法可以確保系統中只存在一個實例,但是當通過反射機制,強行調用單例類的私有構造函數生成多個單例。

(4)序列化/反序列化的單例實現

package com.ycit.singleton;

import java.io.Serializable;

/**
 * @author 江鵬飛
 *	序列化反序列化單例模式的實現
 */
public class SerSingleton implements Serializable {
	String name;
	private SerSingleton() {
		System.out.println("Singleton is  created");
		name="SerSingleton";
	}
	private static SerSingleton instance = new SerSingleton();
	public static SerSingleton getInstance() {
		return instance;
	}
	private Object readResolve(){
		return instance;
	}
}

 

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