常见单例模式汇总(共4种主流,附特点)
1. 饿汉式单例
代码
public class Singleton {
// 类加载直接创建实例
private static final Singleton INSTANCE = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return INSTANCE;
}
}
特点
- 线程天然安全,实现最简单;
- 非懒加载:类加载就创建对象,不用也占内存;
- 适合单例一定会使用的场景。
2. 静态内部类单例(开发很推荐)
public class Singleton {
private Singleton(){}
// 静态内部类,外部类加载不会初始化它
private static class Holder{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance(){
return Holder.INSTANCE;
}
}
特点
- 懒加载、线程安全;
- 无同步锁,并发性能比DCL更好;
- 代码简洁,没有volatile、锁等复杂细节;
- 缺点:不支持有参构造传参。
3. 普通懒汉式(不推荐,多线程不安全)
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
特点
- 懒加载;
- 多线程并发会创建多个实例,线程不安全;
- 仅适合单线程测试学习,项目禁用。
4. 枚举单例(最安全,Effective Java推荐)
public enum Singleton {
INSTANCE;
// 自定义业务方法
public void test(){}
}
// 使用:Singleton.INSTANCE.test();
特点
- 懒加载、线程安全;
- 天然防反射、序列化破坏单例,无漏洞;
- 写法极简;
- 缺点:无法自定义有参构造灵活传参。
简单对比速记
- 饿汉:简单、安全、不懒加载
- 普通懒汉:懒加载、多线程不安全
- DCL双重检查锁:懒加载、安全、并发高,需volatile
- 静态内部类:懒加载、安全、无锁、性能最优
- 枚举单例:绝对安全,防反射序列化