使用场景
- 某种类型的对象具有全局唯一性,例如:Android 中的 Application 对象。
- 避免产生多个对象消耗过多的资源,例如:访问 IO 等资源时。
Java 中的实现方式
- 饿汉模式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
不能按需加载。
- 懒汉模式
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
同步开销较大。
- Double Check Lock
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
synchronized(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
DCL 失效问题:Java 5及其以上版本使用 volatile 关键字修饰 instance 解决。
- 静态内部类
public class Singleton {
private Singleton() {}
public static Singleton getInstance() {
return Instance.INSTANCE;
}
private static class Instance {
private static final Singleton INSTANCE = new Singleton();
}
}
- 枚举
public enum Singleton {
INSTANCE;
}
因为 Java 反序列化机制对枚举类的特殊处理,使得反序列化时不会重新创建对象。
- 容器
public class SingletonManager {
private static Map<String, Object> map = new HashMap();
private SingletonManger() {}
public static void putInstance(String key, Object instance) {
if(!map.containsKey(key)) {
map.put(key, instance);
}
}
public static Object getInstance(String key) {
return map.get(key);
}
}
注意点
- 防止反序列化时重新创建对象
public class Singleton implements Serializeable {
private static final long serialVersionUID = 0L;
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
private Object readResolve() throws ObjectStreamException {
return instance;
}
}