單例模式是一種常見的設計模式,在《Java與模式》一書中,閻宏博士對單例模式做了全面的總結。
單例模式分三種:懶漢式單例、餓漢式單例、登記式單例三種。
單例模式有一下特點:
1、單例類隻能有一個執行個體。
2、單例類必須自己建立自己的唯一執行個體。
3、單例類必須給所有其他對象提供這一執行個體。
說明:一下的代碼來自閻宏博士的《Java與模式》一書,其中對一些類的寫法做調整(符合Java1.5的習慣),另外還加了測試方法。
一、懶漢式單例
在類被加載的時候,唯一執行個體已經被建立。這個設計模式在Java中容易實作,在别的語言中難以實作。
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-9-11
* Time: 14:57:08
* <> 單例模式-懶漢式單例
*/
public class LazySingleton {
/**
* 私有靜态對象,加載時候不做初始化
*/
private static LazySingleton m_intance=null;
* 私有構造方法,避免外部建立執行個體
private LazySingleton(){
}
* 靜态工廠方法,傳回此類的唯一執行個體.
* 當發現執行個體沒有初始化的時候,才初始化.
* @return LazySingleton
synchronized public static LazySingleton getInstance(){
if(m_intance==null){
m_intance=new LazySingleton();
}
return m_intance;
}
二、餓漢式單例
在類加載的時候不建立單例執行個體。隻有在第一次請求執行個體的時候的時候建立,并且隻在第一次建立後,以後不再建立該類的執行個體。
* Time: 14:45:25
* <> 單例模式-餓漢式單例
public class EagerSingleton {
* 私有的(private)唯一(static final)執行個體成員,在類加載的時候就建立好了單例對象
private static final EagerSingleton m_instance = new EagerSingleton();
private EagerSingleton() {
* 靜态工廠方法,傳回此類的唯一執行個體.
* @return EagerSingleton
public static EagerSingleton getInstance() {
return m_instance;
三、登記式單例
這個單例實際上維護的是一組單例類的執行個體,将這些執行個體存放在一個Map(登記薄)中,對于已經登記過的執行個體,則從工廠直接傳回,對于沒有登記的,則先登記,而後傳回。
* Date: 2005-9-11
* Time: 15:20:16
* <> 單例模式- 登記式單例
public class RegSingleton {
* 登記薄,用來存放所有登記的執行個體
private static Map m_registry = new HashMap();
//在類加載的時候添加一個執行個體到登記薄
static {
RegSingleton x = new RegSingleton();
m_registry.put(x.getClass().getName(), x);
* 受保護的預設構造方法
protected RegSingleton() {
* 靜态工廠方法,傳回指定登記對象的唯一執行個體;
* 對于已登記的直接取出傳回,對于還未登記的,先登記,然後取出傳回
* @param name
* @return RegSingleton
public static RegSingleton getInstance(String name) {
if (name == null) {
name = "RegSingleton";
if (m_registry.get(name) == null) {
try {
m_registry.put(name, (RegSingleton) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
} catch (ClassNotFoundException e) {
}
return m_registry.get(name);
* 一個示意性的商業方法
* @return String
public String about() {
return "Hello,I am RegSingleton!";