java 设计模式--单例模式
懒汉式单例
懒汉式单例类在第一次被引用时将自己实例化。这种简单实现的问题在于,每次访问getInstance()都需要同步操作,而事实上同步只在第一次访问时有意义。
public class LazySingleton {
private static LazySingleton m_intance=null;
//私有构造方法,避免外部创建实例
private LazySingleton(){
}
// 静态工厂方法,返回此类的唯一实例.
// 当发现实例没有初始化的时候,才初始化.
//通过synchronized关键字,同步了不同线程对getInstance()的访问。
synchronized public static LazySingleton getInstance(){
if(m_intance==null){
m_intance=new LazySingleton();
}
return m_intance;
}
}
饿汉式单例
在类被加载时,就会将自己实例化。
public class EagerSingleton {
// 私有的(private)唯一(static final)实例成员,在类加载的时候就创建好了单例对象
private static final EagerSingleton m_instance = new EagerSingleton();
// 私有构造方法,避免外部创建实例
private EagerSingleton() {
}
// 静态工厂方法,返回此类的唯一实例.
public static EagerSingleton getInstance() {
return m_instance;
}
登记式单例
登记式单例类是GoF 为了克服饿汉式单例类及懒汉式单例类均不可继承的缺点而设计的。
这个单例实际上维护的是一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。
import java.util.HashMap;
import java.util.Map;
public class RegSingleton {
// 登记薄,用来存放所有登记的实例
private static Map<String, RegSingleton> m_registry = new HashMap();
//在类加载的时候添加一个实例到登记薄
static {
RegSingleton x = new RegSingleton();
m_registry.put(x.getClass().getName(), x);
}
// 受保护的默认构造方法
protected 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) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return m_registry.get(name);