单例模式类规则:
- 这个类只有一个实例。单例模式的核心。
- 这个类自已负责创建这个实例。类自己负责创建实例,才能保证只有一个实例。
- 这个实例是非私有的。如果实例私有,这个类不能被任何类使用,这是没有意义的。
单例模式类实现规则:
- 构造方法私有。
- 有一个能持有自身实例的私有静态成员变量。
- 有一个能提供自身实例的公有静态成员方法。
为什么要使用单例模式:
- 从业务的角度来看,有些核心对象在系统中必须只有一个实例,比如员工可以有多个,经理只有一个。
- 从技术的角度来看,单例类实例只创建一次,对一些大类反复创建实例很耗资源,使用单例模式可以节省资源。
单例模式分类:
饿汉式: 类加载时创建实例。
public class Singleton {
private final static Singleton uniqueInstance = new Singleton();
private Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
return uniqueInstance;
}
// other methods...
}
懒汉式: 类被调用时创建实例。
例一:使用双重检查成例同步创建实例动作, JDK 1.5 后才能用这种方法。
public class Singleton {
// volatile is very important for uniqueInstance consistency.
private volatile static Singleton uniqueInstance = null;
private Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
// first check no need to synchronize.
if (uniqueInstance == null) {
// second check need to synchronize, but only run limit times.
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
// Other methods...
}
例二:使用静态私有内部类实现创建实例动作。
public class Singleton {
// an inner class holder the uniqueInstance.
private static class SingletonHolder {
static final Singleton uniqueInstance = new Singleton();
}
private Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
return SingletonHolder.uniqueInstance;
}
// Other methods...
}
注册式:子类被调用时创建子类实例,子类继承单例父类。
例:使用双重检查成例同步创建实例动作, JDK 1.5 后才能用这种方法
public class RegSingleton {
static private HashMap m_registry = new HashMap();
protected RegSingleton() {
}
public static RegSingleton getInstance(Class regSingletonClass) {
if(regSingletonClass != null) {
if(!m_registry.containsKey(regSingletonClass.getName())) {
synchronized(RegSingleton.class) {
if(!m_registry.containsKey(regSingletonClass.getName())) {
Constructor constructor =
regSingletonClass.getDeclaredConstructor(new Class[]{});
constructor.setAccessible(true);
RegSingleton regSingleton =
(RegSingleton)constructor.newInstance(null);
if(regSingleton != null) {
m_registry.put(regSingletonClass.getName(), regSingleton);
}
}
}
}
}
return (RegSingleton)m_registry.get(regSingletonClass.getName());
}
}
// sub-class implements RegSingleton.
public class RegSingletonChild extends RegSingleton {
private RegSingletonChild() {
}
static public RegSingletonChild getInstance() {
return (RegSingletonChild) RegSingleton
.getInstance(RegSingletonChild.class );
}
public String about() {
return "Hello, I am RegSingletonChild.";
}
}