Skip to content

单例

更新: 6/28/2025 字数: 0 字 时长: 0 分钟

定义

单例模式 (Singleton Pattern) 确保一个类只有一个实例,并提供全局访问点。该模式通过私有化构造器、提供静态获取方法来实现对象的唯一性控制。

角色

  • 单例类 (Singleton):包含私有静态实例变量、私有构造器、公共静态访问方法

实现

饿汉式(线程安全)

java
public class EagerSingleton {
    // 类加载时立即初始化
    private static final EagerSingleton instance = new EagerSingleton();
    
    // 私有构造器防止外部实例化
    private EagerSingleton() {
        System.out.println("饿汉式单例初始化");
    }
    
    public static EagerSingleton getInstance() {
        return instance;
    }
}

懒汉式(线程不安全)

java
public class LazySingleton {
    private static LazySingleton instance;
    
    private LazySingleton() {
        System.out.println("懒汉式单例初始化");
    }
    
    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

线程安全懒汉式(双重检查锁定)

java
public class ThreadSafeSingleton {
    private static volatile ThreadSafeSingleton instance;
    
    private ThreadSafeSingleton() {
        System.out.println("线程安全单例初始化");
    }
    
    public static ThreadSafeSingleton getInstance() {
        if (instance == null) {
            synchronized (ThreadSafeSingleton.class) {
                if (instance == null) {
                    instance = new ThreadSafeSingleton();
                }
            }
        }
        return instance;
    }
}

静态内部类实现(推荐)

java
public class StaticInnerSingleton {
    private StaticInnerSingleton() {
        System.out.println("静态内部类单例初始化");
    }
    
    private static class SingletonHolder {
        private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();
    }
    
    public static StaticInnerSingleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

枚举实现(最佳实践)

java
public enum EnumSingleton {
    INSTANCE;
    
    public void doSomething() {
        System.out.println("枚举单例方法执行");
    }
}

优缺点

优点:

  1. 严格控制实例数量,节省系统资源
  2. 全局访问点便于管理和扩展
  3. 避免频繁创建销毁对象,提高性能

缺点:

  1. 扩展困难(需要修改单例类本身)
  2. 违背单一职责原则(同时承担实例控制和业务逻辑)
  3. 多线程环境下需要特殊处理
  4. 单元测试困难(无法模拟替代实现)

应用场景

  1. 需要频繁创建销毁但又要控制数量的对象(线程池、缓存)
  2. 需要全局访问点的共享资源(配置管理、日志系统)
  3. 重量级资源对象(数据库连接池、文件系统)
  4. 需要唯一实例的核心组件(任务管理器、设备驱动程序)

与其他模式的关系

  • 与工厂模式:单例常作为工厂模式的实现基础(如抽象工厂中的具体工厂)
  • 与享元模式:都是对象复用技术,但单例确保唯一实例,享元管理多个相似对象
  • 与状态模式:状态对象常设计为单例
  • 与门面模式:门面对象通常实现为单例

JDK 中的单例模式

  1. java.lang.Runtime:饿汉式实现
  2. java.awt.Desktop:懒汉式实现
  3. java.lang.System:系统级单例
  4. java.util.Collections#EMPTY_LIST:不可变空集合单例

注意事项

  1. 序列化攻击:实现readResolve()方法防止反序列化创建新实例
  2. 反射攻击:构造器中添加防止重复初始化的检查
  3. 克隆攻击:重写clone()方法并抛出异常

贡献者

The avatar of contributor named as AKAcxp AKAcxp

页面历史