Singleton Pattern
什么是单例模式
单例模式(Singleton Pattern):确保某一个类只有一个实例,向整个系统提供这个唯一实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。
单例模式是结构最简单的设计模式一,在它的核心结构中只包含一个被称为单例类的特殊类。
单例模式的各种写法,推荐使用枚举。
因为可以通过AccessibleObject.setAccessbile
方法,使用反射调用私有构造器创建实例,所以需要在构造方法中,让它在被要求创建第二个实例的时候抛出异常。
1. 饿汉式
/*
加载类时就初始化,如果不用浪费内存
*/
public class EagerSingleton {
private static final EagerSingleton EAGER_SINGLETON = new EagerSingleton();
private EagerSingleton() {
}
public static EagerSingleton instance() {
return EAGER_SINGLETON;
}
}
2. 懒汉式
/*
延迟加载,用到时再加载。
必须使用volatile关键字修饰,因为new对象操作不是原子性的,
1. 给Singleton实例分配内存
2. 调用Singleton()构造函数,进行初始化
3. 将mSingle对象指向分配的内存空间
因为按照内存模型中线程工作内存回写到主内存时2、3的步骤是不确定的,当3在前面发生时,即mSingle不为null了,此时切换线程,得到的是未初始化的非空对象,使用时会出错。这就是DCL(Double check Lock)失效问题。
使用volatile禁止指令重排,保证按顺序执行,直接从主内存读写,就不会出错了。
*/
public class LazySingleton {
private static volatile LazySingleton mLazySingleton;
private LazySingleton() {
// if(mLazySingleton != null){
// throw new IllegalAccessError("you should not");
// }
}
// 使用局部变量,并不是必须的,但能提高性能。但并不是必须的
public static LazySingleton instance() {
LazySingleton result = mLazySingleton;
if (result == null) {
synchronized (LazySingleton.class) {
result = mLazySingleton;
if (result == null) {
mLazySingleton = result = new LazySingleton();
}
}
}
return result;
}
}
3. LoDH式
lazy initialization holder class
,也称作initialize-on-demand holder
,延迟初始化。
/*
饿汉式浪费内存,懒汉式使用volatile造成性能损耗。所以:
使用HolderClass包裹,既延迟加载,又不浪费性能
*/
public class LoDHSingleton {
private LoDHSingleton() {
}
private static class HolderClass {
private static final LoDHSingleton LO_DH_SINGLETON = new LoDHSingleton();
}
public static LoDHSingleton instance() {
return HolderClass.LO_DH_SINGLETON;
}
}
4. 使用枚举
public enum EnumSingleton {
INSTANCE;
}