Singleton Pattern作为经常遇到的模式,被人们津津乐道。
Singleton Pattern的三大特点:
(1) Singleton类只能由一个实例(必须是private constructor)
(2) Singleton类必须自己创建自己的惟一instance
(3) Singleton类必须为所有其他对象提供自己的这个唯一的instance.
这里Singleton Pattern分为了三种,分别是EagerSingleton, LazySingleton和RegSingleton(登记式)
一、其中EagerSingleton最容易理解,也是最常用的:
public class EagerSingleton{
private static final EagerSingleton m_instance=new EagerSingleton();
private EagerSingleton(){}
public static EagerSingleton getInstance(){
return m_instance;
}
}
注意几点:(1)private constructor,该类不可被继承
(2) private static final提供了唯一不变的实例,而这一实例由static getInstance()来返回
(3) 该类在加载时,就创建出了实例。
二、LazySingleton
public class LasySingleton{
private static LasySingleton m_instance = null;
private LasySingleton(){}
synchronized public static LasySingleton getInstance(){
if(m_instance ==null)
m_instance = new LasySingleton();
return m_instance;
}
}
注意:(1)private constructor,该类不可被继承
(2) public static getInstance()函数在懒汉没有实例时,提供一个新的实例。(若类加载器是静态的,则不会进行初始化)
(3) 同步,使得资源耗费比较大。
三、RegSingleton
public class RegSingleton{
private static HashMap m_registry = new HashMap();
static{
RegSingleton x = new RegSingleton();
m_registry.put(x.getClass().getName(), x);
} //保证唯一的RegSingleton实例
protected RegSingleton(){}//保证RegSingleton的继承
public static RegSingleton getInstance(String name){//可以提供RegSingleton或其子类的实例,其中保证RegSingleton的实例唯一
if(name==null)
name=”com.singleton.RegSingleton”;
if(m_registry.get(name)==null)//若需要得到子类的对象
m_registry.put(name, class.forName(name).newInstance());
return (RegSingleton)(m_registry.get(name));
}
}
public class RegSingletonChild extends RegSingleton{
public RegSingletonChild(){}//为允许RegSingleton构造instance,为public
//缺点:可以由子类单独产生不在RegSingleton登记中的实//例,非单例。
Public static RegSingletonChild getInstance(){
Return (RegSingletonChild)RegSingleton.getInstance(“com.singleton.RegSingletonChild”);
}//仅仅为了方便直接从子类中得到子类的实例。
}
GoF指出:这里是由于父类的必须存在才可能有子类的实例。(????)
同时,Singleton类还可以分为stateful, stateless, 注意避免stateful Singleton在多个JVM的分布式系统以及在多个类加载器的情况下使用(在使用了EJB,RMI,JINI的distributed system中)。
Java API中典型的Singleton类有:Runtime类,java.beans.Introspector, java.awt.Toolkit.