单例模式
- 问题由来:多个线程操作同一对象,要保证对象唯一性
- 解决问题:只实例化一个对象
- 解决思路:
- 实例化过程只实例化一次
- 提供返回实例的方法
- 性能指标:线程安全性、性能、懒加载
- 单例模式的分类:
- 饿汉式
public class HungerySingleton {
// 安全,性能好,非懒加载
private static HungerySingleton instance = new HungerySingleton();
private HungerySingleton(){}
public static HungerySingleton getInstance() {
return instance;
}
}
* 懒汉式,双重锁检查
public class HoonSingleton {
private volatile static HoonSingleton instance = null;
//性能好,安全,懒加载
public static HoonSingleton getInstance() {
if(instance == null) {
synchronized (HoonSingleton.class) {
//如果第一个线程执行到这里 不判断,那么会 创建两个对象
if(instance == null) {
instance = new HoonSingleton();
}
}
}
return instance;
}
}
* Holder:声明类的时候,不声明实例变量,而放到内部静态类
public class HolderSingleton {
private HolderSingleton(){}
public static HolderSingleton getInstance() {
return Holder.instance;
}
/**
*
* 静态内部类holder会延迟加载,只有调用 getInstance() 才会进行instance的实例化,实现了懒加载
* 由于这是一个类,只能加载一次,因此也是一个线程安全的
* 应用较广泛
*/
private static class Holder {
private static HolderSingleton instance = new HolderSingleton();
}
}
- 枚举方式
public class EnumSingletonWithHolder {
private EnumSingletonWithHolder() {}
private enum EnumSingleton {
INSTANCE;
private EnumSingletonWithHolder instance;
/**
* 由于是内部类,
* 内部类是延时加载的,也就是说只会在第一次使用时加载
* 因此这个构造函数被加载 仅当getInstance()被调用时
* {@link EnumSingletonWithHolder#getInstance()}
*/
EnumSingleton() {
instance = new EnumSingletonWithHolder();
}
private EnumSingletonWithHolder getInstance() {
return instance;
}
}
public EnumSingletonWithHolder getInstance() {
return EnumSingleton.INSTANCE.getInstance();
}
}