单例模式 7 种实现方式对比表
2026/6/14 23:26:22 网站建设 项目流程
序号实现方式线程安全懒加载性能防止反射破坏防止序列化破坏代码复杂度适用场景
1饿汉式单线程环境简单应用
2懒汉式(线程不安全)单线程环境,性能要求高
3懒汉式(方法同步)多线程但性能要求不高
4双重检查锁(DCL)多线程,性能要求高
5静态内部类推荐使用,兼顾性能和懒加载
6枚举最佳实践,保证绝对单例
7ThreadLocal单例线程内安全线程池环境,线程隔离单例

详细说明

1. 饿汉式

public class EagerSingleton { private static final EagerSingleton instance = new EagerSingleton(); private EagerSingleton() {} public static EagerSingleton getInstance() { return instance; } }

优点: 实现简单,线程安全
缺点: 类加载时就初始化,浪费内存

2. 懒汉式(线程不安全)

public class LazySingleton { private static LazySingleton instance; private LazySingleton() {} public static LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; } }

优点: 懒加载,需要时才创建
缺点: 线程不安全,可能创建多个实例

3. 懒汉式(方法同步)

public class SyncSingleton { private static SyncSingleton instance; private SyncSingleton() {} public static synchronized SyncSingleton getInstance() { if (instance == null) { instance = new SyncSingleton(); } return instance; } }

优点: 线程安全,懒加载
缺点: 每次获取都加锁,性能差

4. 双重检查锁(DCL)

public class DCLSingleton { private volatile static DCLSingleton instance; private DCLSingleton() {} public static DCLSingleton getInstance() { if (instance == null) { synchronized (DCLSingleton.class) { if (instance == null) { instance = new DCLSingleton(); } } } return instance; } }

优点: 线程安全,懒加载,性能较好
缺点: JDK1.5+才完全安全,实现稍复杂

5. 静态内部类

public class InnerClassSingleton { private InnerClassSingleton() {} private static class SingletonHolder { private static final InnerClassSingleton instance = new InnerClassSingleton(); } public static InnerClassSingleton getInstance() { return SingletonHolder.instance; } }

优点: 线程安全,懒加载,性能好
缺点: 无法防止反射破坏

6. 枚举(最佳实践)

public enum EnumSingleton { INSTANCE; public void doSomething() { // 业务方法 } }

优点:

  • 绝对防止反射破坏

  • 自动处理序列化

  • 线程安全

  • 代码简洁

缺点: 不是懒加载,枚举类加载时就初始化

7. ThreadLocal单例

public class ThreadLocalSingleton { private static final ThreadLocal<ThreadLocalSingleton> threadLocal = ThreadLocal.withInitial(ThreadLocalSingleton::new); private ThreadLocalSingleton() {} public static ThreadLocalSingleton getInstance() { return threadLocal.get(); } }

优点: 线程内单例,适合线程池环境
缺点: 每个线程有自己的实例,不是真正的全局单例

选择建议

  1. 简单场景:饿汉式

  2. 标准需求:静态内部类(推荐)

  3. 严格要求:枚举(最佳实践)

  4. 线程隔离:ThreadLocal单例

  5. 历史遗留:DCL(注意volatile关键字)

注意事项

  1. 反射攻击防护:只有枚举能天然防止反射破坏,其他方式需要额外防护代码

  2. 序列化问题:实现Serializable接口时,需要添加readResolve()方法

  3. 克隆防护:重写clone()方法,抛出CloneNotSupportedException

  4. 多类加载器:自定义类加载器可能破坏单例,需注意类加载器隔离

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询