一个好的单例模式主要关注的点:
- 是否是线程安全的
- 是否可以实现延时创建对象(在类被加载的时候就被创建了对象)
- 是否可以通过反射后者序列化和反序列化破坏单例
饿汉式
public class Singleton {
private Singleton(){}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
线程安全:是
延时创建对象:否
是否可以通过反射或者序列化反序列化破坏单例:是
懒汉式
public class Singleton {
private Singleton() {}
private static Singleton instance = null;
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
线程安全:否
延时创建对象:是
是否可以通过反射或者序列化反序列化破坏单例:是
DCL+V
public class Singleton {
private Singleton(){}
private static Singleton instance = null;
public static Singleton getInstance() {
if(instance == null) {
Synchronized(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
线程安全:是
延时创建对象:是
是否可以通过反射或者序列化反序列化破坏单例:是
静态内部类
public class Singleton {
private Singleton() {}
private static class Holder {//外部类被类加载,内部类不一定会被类加载
private static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return Holder.instance;
}
}
线程安全;是
延时创建对象:是
是否可以通过反射或者序列化反序列化破坏单例:是
枚举
public enum Singleton {
INSTANCE;
}
线程安全:是
延时创建对象:是
是否可以通过反射或者序列化反序列化破坏单例:否,会抛异常