单例设计模式全方位深度解析

0 阅读16分钟

一、单例模式核心概念

1.1 定义

单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。

1.2 核心要素

  1. 私有构造器:防止外部通过new创建实例
  2. 静态实例变量:保存唯一实例
  3. 静态访问方法:提供全局访问点
  4. 线程安全机制:多线程环境下保证唯一性

二、Java实现方式详解

2.1 饿汉式(Eager Initialization)

/**
 * 饿汉式 - 类加载时初始化
 * 优点:线程安全,实现简单
 * 缺点:浪费资源,无论是否使用都会创建实例
 */
class EagerSingleton {
    // 静态常量,类加载时初始化
    private static final EagerSingleton INSTANCE = new EagerSingleton();
    
    // 私有构造器
    private EagerSingleton() {
        // 防止反射攻击
        if (INSTANCE != null) {
            throw new RuntimeException("禁止通过反射创建实例");
        }
        System.out.println("EagerSingleton 实例被创建");
    }
    
    // 全局访问点
    public static EagerSingleton getInstance() {
        return INSTANCE;
    }
    
    // 防止反序列化破坏单例
    protected Object readResolve() {
        return INSTANCE;
    }
}

适用场景

  • 实例创建成本低
  • 应用启动时就需要使用的实例
  • 线程池、数据库连接池等资源

2.2 懒汉式(Lazy Initialization)

import java.util.concurrent.atomic.AtomicReference;

/**
 * 懒汉式 - 延迟加载
 * 演变过程:非线程安全 → 方法同步 → 双重检查锁 → 静态内部类 → 枚举
 */
class LazySingleton {
    
    // 版本1:非线程安全(不推荐)
    static class Version1 {
        private static Version1 instance;
        
        private Version1() {}
        
        public static Version1 getInstance() {
            if (instance == null) {
                instance = new Version1(); // 多线程下可能创建多个实例
            }
            return instance;
        }
    }
    
    // 版本2:方法同步(效率低)
    static class Version2 {
        private static Version2 instance;
        
        private Version2() {}
        
        public static synchronized Version2 getInstance() {
            if (instance == null) {
                instance = new Version2();
            }
            return instance;
        }
    }
    
    // 版本3:双重检查锁(DCL)
    static class Version3 {
        // volatile禁止指令重排序,确保可见性
        private static volatile Version3 instance;
        
        private Version3() {
            // 防止指令重排序导致的初始化问题
        }
        
        public static Version3 getInstance() {
            if (instance == null) { // 第一次检查,避免不必要的同步
                synchronized (Version3.class) {
                    if (instance == null) { // 第二次检查,确保线程安全
                        instance = new Version3();
                        // 对象创建的三步:
                        // 1. 分配内存空间
                        // 2. 初始化对象
                        // 3. 将引用指向内存地址
                        // volatile防止步骤2和3重排序
                    }
                }
            }
            return instance;
        }
    }
    
    // 版本4:静态内部类(推荐)
    static class Version4 {
        private Version4() {}
        
        // 静态内部类在第一次使用时加载
        private static class SingletonHolder {
            private static final Version4 INSTANCE = new Version4();
            
            static {
                System.out.println("SingletonHolder 类被加载");
            }
        }
        
        public static Version4 getInstance() {
            return SingletonHolder.INSTANCE;
        }
    }
    
    // 版本5:CAS实现(无锁)
    static class Version5 {
        private static final AtomicReference<Version5> INSTANCE = 
            new AtomicReference<>();
        
        private Version5() {}
        
        public static Version5 getInstance() {
            for (;;) {
                Version5 current = INSTANCE.get();
                if (current != null) {
                    return current;
                }
                current = new Version5();
                if (INSTANCE.compareAndSet(null, current)) {
                    return current;
                }
                // CAS失败,说明其他线程已经创建实例,继续循环获取
            }
        }
    }
}

2.3 枚举式(Joshua Bloch推荐)

/**
 * 枚举单例 - Effective Java推荐
 * 优点:绝对防止多次实例化,防止反射和序列化攻击
 */
enum EnumSingleton {
    INSTANCE;
    
    // 可以添加实例变量和方法
    private String config = "default";
    private int counter = 0;
    
    // 枚举的构造器是私有的
    EnumSingleton() {
        System.out.println("EnumSingleton 初始化");
    }
    
    public void doSomething() {
        counter++;
        System.out.println("执行操作,计数:" + counter);
    }
    
    public String getConfig() {
        return config;
    }
    
    public void setConfig(String config) {
        this.config = config;
    }
    
    // 枚举单例的优势:
    // 1. 防止反射攻击:反射不能创建枚举实例
    // 2. 防止序列化攻击:枚举的序列化机制保证唯一性
    // 3. 线程安全:枚举实例的创建是线程安全的
    // 4. 简洁明了:代码最简洁
}

2.4 线程内单例(ThreadLocal)

/**
 * ThreadLocal单例 - 每个线程独立的单例
 * 应用场景:ThreadLocal变量,数据库连接,Session管理
 */
class ThreadLocalSingleton {
    private static final ThreadLocal<ThreadLocalSingleton> THREAD_LOCAL_INSTANCE =
        ThreadLocal.withInitial(() -> {
            System.out.println(Thread.currentThread().getName() + " 创建 ThreadLocalSingleton");
            return new ThreadLocalSingleton();
        });
    
    private ThreadLocalSingleton() {}
    
    public static ThreadLocalSingleton getInstance() {
        return THREAD_LOCAL_INSTANCE.get();
    }
    
    public void remove() {
        THREAD_LOCAL_INSTANCE.remove();
    }
    
    // 实例变量,每个线程独立
    private final ThreadLocal<String> threadData = new ThreadLocal<>();
    
    public void setThreadData(String data) {
        threadData.set(data);
    }
    
    public String getThreadData() {
        return threadData.get();
    }
}

2.5 登记式单例(Registry Singleton)

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 登记式单例 - Spring IoC容器风格
 * 应用场景:管理多个单例对象
 */
class RegistrySingleton {
    // 单例注册表
    private static final Map<String, Object> SINGLETON_REGISTRY = 
        new ConcurrentHashMap<>();
    
    private RegistrySingleton() {}
    
    /**
     * 注册单例
     */
    public static void registerSingleton(String name, Object singleton) {
        synchronized (SINGLETON_REGISTRY) {
            if (!SINGLETON_REGISTRY.containsKey(name)) {
                SINGLETON_REGISTRY.put(name, singleton);
            }
        }
    }
    
    /**
     * 获取单例
     */
    @SuppressWarnings("unchecked")
    public static <T> T getSingleton(String name) {
        return (T) SINGLETON_REGISTRY.get(name);
    }
    
    /**
     * 按类型获取单例,不存在则创建
     */
    @SuppressWarnings("unchecked")
    public static <T> T getSingleton(Class<T> clazz) {
        String className = clazz.getName();
        Object singleton = SINGLETON_REGISTRY.get(className);
        
        if (singleton == null) {
            synchronized (clazz) {
                singleton = SINGLETON_REGISTRY.get(className);
                if (singleton == null) {
                    try {
                        singleton = clazz.getDeclaredConstructor().newInstance();
                        SINGLETON_REGISTRY.put(className, singleton);
                    } catch (Exception e) {
                        throw new RuntimeException("创建单例失败: " + className, e);
                    }
                }
            }
        }
        
        return (T) singleton;
    }
    
    /**
     * 获取所有单例
     */
    public static Map<String, Object> getAllSingletons() {
        return new ConcurrentHashMap<>(SINGLETON_REGISTRY);
    }
    
    /**
     * 销毁单例
     */
    public static void destroySingleton(String name) {
        synchronized (SINGLETON_REGISTRY) {
            Object singleton = SINGLETON_REGISTRY.remove(name);
            if (singleton instanceof AutoCloseable) {
                try {
                    ((AutoCloseable) singleton).close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

三、应用场景(详细分类)

3.1 系统级单例

3.1.1 配置管理器

/**
 * 配置管理器 - 系统配置统一管理
 */
class ConfigManager {
    private static final ConfigManager INSTANCE = new ConfigManager();
    private final Properties config = new Properties();
    private volatile long lastModified = 0;
    private final File configFile;
    
    private ConfigManager() {
        configFile = new File("application.properties");
        loadConfig();
        startConfigWatcher();
    }
    
    public static ConfigManager getInstance() {
        return INSTANCE;
    }
    
    private void loadConfig() {
        try (FileInputStream fis = new FileInputStream(configFile)) {
            config.load(fis);
            lastModified = configFile.lastModified();
            System.out.println("配置文件加载完成");
        } catch (IOException e) {
            throw new RuntimeException("加载配置文件失败", e);
        }
    }
    
    private void startConfigWatcher() {
        Thread watcher = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    Thread.sleep(5000); // 每5秒检查一次
                    if (configFile.lastModified() > lastModified) {
                        loadConfig();
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        watcher.setDaemon(true);
        watcher.start();
    }
    
    public String getProperty(String key) {
        return config.getProperty(key);
    }
    
    public String getProperty(String key, String defaultValue) {
        return config.getProperty(key, defaultValue);
    }
    
    public int getIntProperty(String key, int defaultValue) {
        String value = getProperty(key);
        if (value != null) {
            try {
                return Integer.parseInt(value);
            } catch (NumberFormatException e) {
                // 忽略格式错误
            }
        }
        return defaultValue;
    }
}

3.1.2 资源池管理器

/**
 * 数据库连接池管理器
 */
class ConnectionPoolManager {
    private static volatile ConnectionPoolManager instance;
    private final List<Connection> pool = new ArrayList<>();
    private final int maxSize = 10;
    private final String url = "jdbc:mysql://localhost:3306/test";
    private final String username = "root";
    private final String password = "password";
    
    private ConnectionPoolManager() {
        initializePool();
    }
    
    public static ConnectionPoolManager getInstance() {
        if (instance == null) {
            synchronized (ConnectionPoolManager.class) {
                if (instance == null) {
                    instance = new ConnectionPoolManager();
                }
            }
        }
        return instance;
    }
    
    private void initializePool() {
        for (int i = 0; i < maxSize; i++) {
            try {
                Connection conn = DriverManager.getConnection(url, username, password);
                pool.add(conn);
            } catch (SQLException e) {
                throw new RuntimeException("创建数据库连接失败", e);
            }
        }
    }
    
    public synchronized Connection getConnection() throws SQLException {
        if (pool.isEmpty()) {
            // 池为空,创建新连接
            return DriverManager.getConnection(url, username, password);
        }
        return pool.remove(pool.size() - 1);
    }
    
    public synchronized void releaseConnection(Connection conn) {
        if (pool.size() < maxSize) {
            pool.add(conn);
        } else {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    public synchronized void closeAllConnections() {
        for (Connection conn : pool) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        pool.clear();
    }
}

3.2 业务级单例

3.2.1 缓存管理器

/**
 * 本地缓存管理器
 * 应用场景:热点数据缓存,减少数据库访问
 */
class CacheManager {
    private static final CacheManager INSTANCE = new CacheManager();
    private final Map<String, CacheEntry> cache = new ConcurrentHashMap<>();
    private final ScheduledExecutorService cleaner = Executors.newScheduledThreadPool(1);
    
    private CacheManager() {
        // 定期清理过期缓存
        cleaner.scheduleAtFixedRate(this::cleanExpiredEntries, 1, 1, TimeUnit.MINUTES);
    }
    
    public static CacheManager getInstance() {
        return INSTANCE;
    }
    
    public void put(String key, Object value, long ttlSeconds) {
        long expiryTime = System.currentTimeMillis() + ttlSeconds * 1000;
        cache.put(key, new CacheEntry(value, expiryTime));
    }
    
    public Object get(String key) {
        CacheEntry entry = cache.get(key);
        if (entry == null) {
            return null;
        }
        
        if (entry.isExpired()) {
            cache.remove(key);
            return null;
        }
        
        return entry.value;
    }
    
    public void remove(String key) {
        cache.remove(key);
    }
    
    public void clear() {
        cache.clear();
    }
    
    public int size() {
        return cache.size();
    }
    
    private void cleanExpiredEntries() {
        Iterator<Map.Entry<String, CacheEntry>> it = cache.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, CacheEntry> entry = it.next();
            if (entry.getValue().isExpired()) {
                it.remove();
            }
        }
    }
    
    // 缓存条目
    private static class CacheEntry {
        final Object value;
        final long expiryTime;
        
        CacheEntry(Object value, long expiryTime) {
            this.value = value;
            this.expiryTime = expiryTime;
        }
        
        boolean isExpired() {
            return System.currentTimeMillis() > expiryTime;
        }
    }
}

3.2.2 序列号生成器

/**
 * 分布式序列号生成器(雪花算法简化版)
 * 应用场景:分布式ID生成,订单号生成
 */
class SequenceGenerator {
    private static final SequenceGenerator INSTANCE = new SequenceGenerator();
    
    // 雪花算法参数
    private final long workerId;      // 工作机器ID
    private final long datacenterId;  // 数据中心ID
    private long sequence = 0L;       // 序列号
    private long lastTimestamp = -1L; // 上次时间戳
    
    // 起始时间戳(2024-01-01)
    private final long twepoch = 1704067200000L;
    
    // 位分配
    private final long workerIdBits = 5L;      // 5位工作机器ID
    private final long datacenterIdBits = 5L;  // 5位数据中心ID
    private final long sequenceBits = 12L;     // 12位序列号
    
    // 最大值
    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
    
    // 移位
    private final long workerIdShift = sequenceBits;
    private final long datacenterIdShift = sequenceBits + workerIdBits;
    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
    
    private SequenceGenerator() {
        // 从系统环境或配置读取
        this.workerId = Long.parseLong(System.getProperty("worker.id", "1"));
        this.datacenterId = Long.parseLong(System.getProperty("datacenter.id", "1"));
        
        if (workerId > maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException("workerId 超出范围");
        }
        if (datacenterId > maxDatacenterId || datacenterId < 0) {
            throw new IllegalArgumentException("datacenterId 超出范围");
        }
    }
    
    public static SequenceGenerator getInstance() {
        return INSTANCE;
    }
    
    public synchronized long nextId() {
        long timestamp = timeGen();
        
        if (timestamp < lastTimestamp) {
            throw new RuntimeException("时钟回退,拒绝生成ID");
        }
        
        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) & sequenceMask;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }
        
        lastTimestamp = timestamp;
        
        return ((timestamp - twepoch) << timestampLeftShift)
                | (datacenterId << datacenterIdShift)
                | (workerId << workerIdShift)
                | sequence;
    }
    
    private long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }
    
    private long timeGen() {
        return System.currentTimeMillis();
    }
    
    // 批量生成ID
    public synchronized List<Long> batchNextId(int count) {
        List<Long> ids = new ArrayList<>(count);
        for (int i = 0; i < count; i++) {
            ids.add(nextId());
        }
        return ids;
    }
}

3.3 框架级单例

3.3.1 Spring风格的Bean容器

/**
 * 简化版Spring Bean容器
 * 管理单例Bean的生命周期
 */
class BeanContainer {
    private static final BeanContainer INSTANCE = new BeanContainer();
    
    // Bean注册表
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
    private final Map<String, Class<?>> beanDefinitions = new ConcurrentHashMap<>();
    private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
    
    private BeanContainer() {
        // 初始化容器
        registerBeanPostProcessors();
    }
    
    public static BeanContainer getInstance() {
        return INSTANCE;
    }
    
    /**
     * 注册Bean定义
     */
    public void registerBeanDefinition(String beanName, Class<?> beanClass) {
        beanDefinitions.put(beanName, beanClass);
    }
    
    /**
     * 获取Bean
     */
    @SuppressWarnings("unchecked")
    public <T> T getBean(String beanName) {
        // 从单例池获取
        Object bean = singletonObjects.get(beanName);
        if (bean != null) {
            return (T) bean;
        }
        
        // 创建新的单例
        synchronized (singletonObjects) {
            bean = singletonObjects.get(beanName);
            if (bean == null) {
                Class<?> beanClass = beanDefinitions.get(beanName);
                if (beanClass == null) {
                    throw new RuntimeException("未找到Bean定义: " + beanName);
                }
                
                try {
                    // 创建实例
                    bean = beanClass.getDeclaredConstructor().newInstance();
                    
                    // Bean后处理器 - 初始化前
                    for (BeanPostProcessor processor : beanPostProcessors) {
                        bean = processor.postProcessBeforeInitialization(bean, beanName);
                    }
                    
                    // 调用初始化方法
                    if (bean instanceof InitializingBean) {
                        ((InitializingBean) bean).afterPropertiesSet();
                    }
                    
                    // Bean后处理器 - 初始化后
                    for (BeanPostProcessor processor : beanPostProcessors) {
                        bean = processor.postProcessAfterInitialization(bean, beanName);
                    }
                    
                    // 放入单例池
                    singletonObjects.put(beanName, bean);
                    
                } catch (Exception e) {
                    throw new RuntimeException("创建Bean失败: " + beanName, e);
                }
            }
        }
        
        return (T) bean;
    }
    
    /**
     * 按类型获取Bean
     */
    public <T> T getBean(Class<T> requiredType) {
        for (Map.Entry<String, Object> entry : singletonObjects.entrySet()) {
            if (requiredType.isInstance(entry.getValue())) {
                return requiredType.cast(entry.getValue());
            }
        }
        
        // 从定义中查找
        for (Map.Entry<String, Class<?>> entry : beanDefinitions.entrySet()) {
            if (requiredType.isAssignableFrom(entry.getValue())) {
                return getBean(entry.getKey());
            }
        }
        
        throw new RuntimeException("未找到类型为 " + requiredType.getName() + " 的Bean");
    }
    
    private void registerBeanPostProcessors() {
        // 这里可以扫描类路径,自动发现BeanPostProcessor
        // 简化实现:手动添加
        beanPostProcessors.add(new AutowiredAnnotationBeanPostProcessor());
    }
    
    /**
     * 销毁容器
     */
    public void destroy() {
        for (Object bean : singletonObjects.values()) {
            if (bean instanceof DisposableBean) {
                try {
                    ((DisposableBean) bean).destroy();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        singletonObjects.clear();
        beanDefinitions.clear();
    }
    
    // 相关接口
    interface InitializingBean {
        void afterPropertiesSet() throws Exception;
    }
    
    interface DisposableBean {
        void destroy() throws Exception;
    }
    
    interface BeanPostProcessor {
        default Object postProcessBeforeInitialization(Object bean, String beanName) {
            return bean;
        }
        
        default Object postProcessAfterInitialization(Object bean, String beanName) {
            return bean;
        }
    }
    
    static class AutowiredAnnotationBeanPostProcessor implements BeanPostProcessor {
        // 实现自动注入逻辑
    }
}

四、优缺点深度分析

4.1 优点(详细分析)

4.1.1 资源优化

  1. 内存效率

    • 减少重复对象创建
    • 降低JVM堆内存压力
    • 减少GC频率和停顿时间
    • 提高缓存命中率
  2. 性能提升

    • 避免重复初始化开销
    • 减少系统调用(如文件IO、网络IO)
    • 提高响应速度
    • 降低CPU使用率
  3. 资源共享

    • 连接池共享数据库连接
    • 线程池重用线程资源
    • 缓存共享热点数据
    • 配置信息全局共享

4.1.2 系统设计

  1. 访问控制

    • 统一入口,便于权限控制
    • 集中管理,便于监控
    • 操作审计,便于追踪
    • 资源限制,防止滥用
  2. 状态一致性

    • 保证全局状态一致
    • 避免数据不一致问题
    • 简化状态同步逻辑
    • 提高系统稳定性
  3. 架构简化

    • 减少类间耦合
    • 简化依赖关系
    • 提高代码可读性
    • 降低维护成本

4.1.3 业务价值

  1. 成本控制

    • 减少服务器资源消耗
    • 降低数据库连接成本
    • 减少外部API调用次数
    • 提高硬件利用率
  2. 可靠性

    • 避免资源泄漏
    • 防止内存溢出
    • 保证服务可用性
    • 提高系统容错性

4.2 缺点(详细分析)

4.2.1 设计问题

  1. 违反设计原则

    • 违反单一职责原则:既要管业务又要管实例
    • 违反开闭原则:扩展困难
    • 违反依赖倒置原则:依赖具体实现
    • 违反接口隔离原则:接口臃肿
  2. 测试困难

    // 难以测试的单例
    class HardToTestSingleton {
        private static HardToTestSingleton instance;
    
        private HardToTestSingleton() {
            // 复杂的初始化逻辑
            loadConfig();
            initCache();
            startThreads();
        }
    
        public static HardToTestSingleton getInstance() {
            if (instance == null) {
                instance = new HardToTestSingleton();
            }
            return instance;
        }
    
        public void doBusiness() {
            // 业务逻辑依赖于全局状态
        }
    }
    
    // 测试困难
    class TestClass {
        @Test
        public void testBusiness() {
            // 单例状态会影响其他测试
            // 无法隔离测试
            HardToTestSingleton.getInstance().doBusiness();
        }
    }
    
  3. 依赖隐藏

    • 隐式依赖难以发现
    • 依赖关系不明确
    • 增加理解成本
    • 导致循环依赖

4.2.2 实现问题

  1. 线程安全复杂

    • 双重检查锁实现复杂
    • volatile关键字理解困难
    • 指令重排序问题
    • 内存可见性问题
  2. 序列化攻击

    // 易受序列化攻击的单例
    class VulnerableSingleton implements Serializable {
        private static VulnerableSingleton instance = new VulnerableSingleton();
    
        private VulnerableSingleton() {}
    
        public static VulnerableSingleton getInstance() {
            return instance;
        }
    
        // 缺少readResolve方法,会被序列化攻击
    }
    
    // 攻击代码
    class SerializationAttack {
        public static void main(String[] args) throws Exception {
            VulnerableSingleton instance1 = VulnerableSingleton.getInstance();
    
            // 序列化
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(instance1);
    
            // 反序列化
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            VulnerableSingleton instance2 = (VulnerableSingleton) ois.readObject();
    
            System.out.println(instance1 == instance2); // false!
        }
    }
    
  3. 反射攻击

    // 易受反射攻击的单例
    class ReflectionVulnerableSingleton {
        private static ReflectionVulnerableSingleton instance = 
            new ReflectionVulnerableSingleton();
    
        private ReflectionVulnerableSingleton() {}
    
        public static ReflectionVulnerableSingleton getInstance() {
            return instance;
        }
    }
    
    // 攻击代码
    class ReflectionAttack {
        public static void main(String[] args) throws Exception {
            ReflectionVulnerableSingleton instance1 = 
                ReflectionVulnerableSingleton.getInstance();
    
            // 通过反射创建新实例
            Constructor<ReflectionVulnerableSingleton> constructor = 
                ReflectionVulnerableSingleton.class.getDeclaredConstructor();
            constructor.setAccessible(true);
            ReflectionVulnerableSingleton instance2 = constructor.newInstance();
    
            System.out.println(instance1 == instance2); // false!
        }
    }
    

4.2.3 运行时问题

  1. 内存泄漏

    class MemoryLeakSingleton {
        private static MemoryLeakSingleton instance;
        private final Map<String, byte[]> cache = new HashMap<>();
    
        private MemoryLeakSingleton() {}
    
        public static MemoryLeakSingleton getInstance() {
            if (instance == null) {
                instance = new MemoryLeakSingleton();
            }
            return instance;
        }
    
        public void cacheData(String key, byte[] data) {
            cache.put(key, data); // 可能积累大量数据
        }
    
        // 缺少清理方法
    }
    
  2. 性能瓶颈

    • 锁竞争导致性能下降
    • 单点故障风险
    • 扩展性受限
    • 难以水平扩展
  3. 生命周期管理

    • 初始化时机难以控制
    • 销毁时机不明确
    • 资源清理困难
    • 异常处理复杂

五、使用要点(最佳实践)

5.1 选择策略

/**
 * 单例模式选择决策树
 */
class SingletonSelection {
    
    /**
     * 根据需求选择单例实现
     */
    public static String selectSingletonImplementation(Requirements req) {
        if (req.isPreventReflectionAttack() && req.isPreventSerializationAttack()) {
            return "使用枚举单例"; // 最安全
        }
        
        if (req.isLazyInitialization()) {
            if (req.isHighPerformance()) {
                if (req.isThreadSafe()) {
                    return "使用双重检查锁"; // 高性能线程安全
                } else {
                    return "使用CAS单例"; // 无锁高性能
                }
            } else {
                return "使用静态内部类"; // 延迟加载,简单安全
            }
        } else {
            if (req.isSimpleImplementation()) {
                return "使用饿汉式"; // 最简单
            } else {
                return "使用枚举单例"; // 推荐默认
            }
        }
    }
    
    static class Requirements {
        boolean lazyInitialization;    // 是否需要延迟加载
        boolean threadSafe;           // 是否需要线程安全
        boolean highPerformance;      // 是否需要高性能
        boolean simpleImplementation; // 是否需要简单实现
        boolean preventReflectionAttack;    // 是否需要防止反射攻击
        boolean preventSerializationAttack; // 是否需要防止序列化攻击
        boolean distributedEnvironment;     // 是否在分布式环境
        
        // getters...
    }
}

5.2 线程安全最佳实践

/**
 * 线程安全的单例实现模板
 */
abstract class ThreadSafeSingleton<T> {
    // 使用静态内部类实现延迟加载和线程安全
    private static class SingletonHolder<T> {
        private static volatile Object instance;
        
        static <T> T getInstance(Supplier<T> creator) {
            if (instance == null) {
                synchronized (SingletonHolder.class) {
                    if (instance == null) {
                        instance = creator.get();
                    }
                }
            }
            @SuppressWarnings("unchecked")
            T result = (T) instance;
            return result;
        }
    }
    
    protected abstract T createInstance();
    
    public final T getInstance() {
        return SingletonHolder.getInstance(this::createInstance);
    }
}

// 使用示例
class MySingleton extends ThreadSafeSingleton<MySingleton> {
    private MySingleton() {
        // 复杂的初始化
    }
    
    @Override
    protected MySingleton createInstance() {
        return new MySingleton();
    }
}

5.3 防御性编程

/**
 * 防御性单例 - 防止所有攻击
 */
class DefensiveSingleton implements Serializable, Cloneable {
    private static final long serialVersionUID = 1L;
    
    // 使用枚举Holder防止反射攻击
    private enum SingletonHolder {
        INSTANCE;
        
        private final DefensiveSingleton instance;
        
        SingletonHolder() {
            instance = new DefensiveSingleton();
        }
        
        private DefensiveSingleton getInstance() {
            return instance;
        }
    }
    
    private DefensiveSingleton() {
        // 防止反射攻击
        if (SingletonHolder.INSTANCE.instance != null) {
            throw new RuntimeException("禁止通过反射创建实例");
        }
        System.out.println("DefensiveSingleton 初始化");
    }
    
    public static DefensiveSingleton getInstance() {
        return SingletonHolder.INSTANCE.getInstance();
    }
    
    // 防止序列化攻击
    protected Object readResolve() {
        return getInstance();
    }
    
    // 防止克隆攻击
    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("单例对象不允许克隆");
    }
    
    // 防止反序列化攻击
    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        throw new InvalidObjectException("禁止反序列化单例对象");
    }
    
    private void writeObject(ObjectOutputStream oos) throws IOException {
        throw new InvalidObjectException("禁止序列化单例对象");
    }
}

5.4 测试友好设计

/**
 * 可测试的单例设计
 */
class TestableSingleton {
    private static TestableSingleton instance;
    private final Dependency dependency;
    
    // 包私有构造器,便于测试
    TestableSingleton(Dependency dependency) {
        this.dependency = dependency;
    }
    
    // 生产环境使用
    public static TestableSingleton getInstance() {
        if (instance == null) {
            synchronized (TestableSingleton.class) {
                if (instance == null) {
                    instance = new TestableSingleton(new RealDependency());
                }
            }
        }
        return instance;
    }
    
    // 测试环境使用
    static void setTestInstance(TestableSingleton testInstance) {
        instance = testInstance;
    }
    
    // 重置实例(仅用于测试)
    static void reset() {
        instance = null;
    }
    
    public void doBusiness() {
        dependency.doSomething();
    }
    
    // 依赖接口
    interface Dependency {
        void doSomething();
    }
    
    // 真实依赖
    static class RealDependency implements Dependency {
        @Override
        public void doSomething() {
            // 真实的业务逻辑
        }
    }
    
    // Mock依赖
    static class MockDependency implements Dependency {
        @Override
        public void doSomething() {
            // Mock实现
        }
    }
}

// 测试用例
class TestableSingletonTest {
    @Before
    public void setUp() {
        TestableSingleton.reset();
    }
    
    @Test
    public void testBusiness() {
        // 使用Mock依赖
        TestableSingleton.setTestInstance(
            new TestableSingleton(new MockDependency())
        );
        
        TestableSingleton instance = TestableSingleton.getInstance();
        instance.doBusiness();
        // 验证行为
    }
}

5.5 Spring集成最佳实践

/**
 * 在Spring中使用单例的最佳实践
 */
@Configuration
class SingletonSpringConfig {
    
    /**
     * 方法1:使用@Bean注解
     * Spring默认单例,但可以控制初始化
     */
    @Bean
    @Lazy  // 延迟初始化
    public ExpensiveService expensiveService() {
        return new ExpensiveService();
    }
    
    /**
     * 方法2:结合@PostConstruct@PreDestroy
     * 管理单例生命周期
     */
    @Bean
    public LifecycleSingleton lifecycleSingleton() {
        return new LifecycleSingleton();
    }
    
    /**
     * 方法3:使用FactoryBean
     * 复杂的单例创建逻辑
     */
    @Bean
    public ComplexSingletonFactory complexSingletonFactory() {
        return new ComplexSingletonFactory();
    }
}

/**
 * 生命周期管理的单例
 */
class LifecycleSingleton {
    
    @PostConstruct
    public void init() {
        // 初始化逻辑
        System.out.println("LifecycleSingleton 初始化");
    }
    
    public void doSomething() {
        // 业务逻辑
    }
    
    @PreDestroy
    public void destroy() {
        // 清理逻辑
        System.out.println("LifecycleSingleton 销毁");
    }
}

/**
 * 工厂Bean创建单例
 */
class ComplexSingletonFactory implements FactoryBean<ComplexSingleton> {
    
    private ComplexSingleton instance;
    
    @Override
    public ComplexSingleton getObject() throws Exception {
        if (instance == null) {
            synchronized (this) {
                if (instance == null) {
                    instance = createComplexSingleton();
                }
            }
        }
        return instance;
    }
    
    @Override
    public Class<?> getObjectType() {
        return ComplexSingleton.class;
    }
    
    @Override
    public boolean isSingleton() {
        return true;
    }
    
    private ComplexSingleton createComplexSingleton() {
        // 复杂的创建逻辑
        return new ComplexSingleton();
    }
}

/**
 * 在非Spring环境中模拟Spring的单例管理
 */
class SingletonManager {
    private static final Map<String, Object> singletons = new ConcurrentHashMap<>();
    private static final Map<String, Runnable> destroyCallbacks = new ConcurrentHashMap<>();
    
    /**
     * 注册单例
     */
    public static <T> void registerSingleton(String name, T instance) {
        if (singletons.containsKey(name)) {
            throw new IllegalStateException("单例已存在: " + name);
        }
        singletons.put(name, instance);
    }
    
    /**
     * 注册带销毁回调的单例
     */
    public static <T> void registerSingleton(String name, T instance, Runnable destroyCallback) {
        registerSingleton(name, instance);
        if (destroyCallback != null) {
            destroyCallbacks.put(name, destroyCallback);
        }
    }
    
    /**
     * 获取单例
     */
    @SuppressWarnings("unchecked")
    public static <T> T getSingleton(String name) {
        return (T) singletons.get(name);
    }
    
    /**
     * 销毁所有单例
     */
    public static void destroyAll() {
        // 按注册的逆序销毁
        List<String> names = new ArrayList<>(destroyCallbacks.keySet());
        Collections.reverse(names);
        
        for (String name : names) {
            try {
                destroyCallbacks.get(name).run();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        singletons.clear();
        destroyCallbacks.clear();
    }
}

六、实战案例:完整的单例应用

/**
 * 实战案例:全局事件总线(单例实现)
 * 应用场景:组件间通信,解耦业务模块
 */
class GlobalEventBus {
    // 枚举实现单例
    public enum Instance {
        INSTANCE;
        
        private final EventBus eventBus;
        private final Map<Class<?>, List<EventHandler>> handlers = new ConcurrentHashMap<>();
        private final ExecutorService executor = Executors.newFixedThreadPool(4);
        
        Instance() {
            this.eventBus = new EventBus("GlobalEventBus");
        }
        
        /**
         * 注册事件处理器
         */
        public <T> void register(Class<T> eventType, EventHandler<T> handler) {
            handlers.computeIfAbsent(eventType, k -> new CopyOnWriteArrayList<>())
                   .add(handler);
        }
        
        /**
         * 取消注册
         */
        public <T> void unregister(Class<T> eventType, EventHandler<T> handler) {
            List<EventHandler> list = handlers.get(eventType);
            if (list != null) {
                list.remove(handler);
            }
        }
        
        /**
         * 发布事件(同步)
         */
        public <T> void publish(T event) {
            List<EventHandler> list = handlers.get(event.getClass());
            if (list != null) {
                for (EventHandler handler : list) {
                    try {
                        handler.handle(event);
                    } catch (Exception e) {
                        // 记录日志,但不影响其他处理器
                        System.err.println("事件处理失败: " + e.getMessage());
                    }
                }
            }
        }
        
        /**
         * 发布事件(异步)
         */
        public <T> void publishAsync(T event) {
            executor.submit(() -> publish(event));
        }
        
        /**
         * 关闭事件总线
         */
        public void shutdown() {
            executor.shutdown();
            try {
                if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
                    executor.shutdownNow();
                }
            } catch (InterruptedException e) {
                executor.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }
    
    // 便捷访问方法
    public static GlobalEventBus getInstance() {
        return Instance.INSTANCE.eventBus;
    }
    
    public static <T> void registerHandler(Class<T> eventType, EventHandler<T> handler) {
        Instance.INSTANCE.register(eventType, handler);
    }
    
    public static <T> void publishEvent(T event) {
        Instance.INSTANCE.publish(event);
    }
    
    public static <T> void publishEventAsync(T event) {
        Instance.INSTANCE.publishAsync(event);
    }
    
    public static void shutdown() {
        Instance.INSTANCE.shutdown();
    }
    
    // 事件处理器接口
    @FunctionalInterface
    public interface EventHandler<T> {
        void handle(T event);
    }
    
    // 事件总线
    static class EventBus {
        private final String name;
        
        EventBus(String name) {
            this.name = name;
        }
        
        public String getName() {
            return name;
        }
    }
    
    // 使用示例
    static class UserLoginEvent {
        private final String username;
        private final long timestamp;
        
        public UserLoginEvent(String username) {
            this.username = username;
            this.timestamp = System.currentTimeMillis();
        }
        
        public String getUsername() { return username; }
        public long getTimestamp() { return timestamp; }
    }
    
    static class OrderCreatedEvent {
        private final String orderId;
        private final double amount;
        
        public OrderCreatedEvent(String orderId, double amount) {
            this.orderId = orderId;
            this.amount = amount;
        }
        
        public String getOrderId() { return orderId; }
        public double getAmount() { return amount; }
    }
    
    public static void main(String[] args) {
        // 注册事件处理器
        GlobalEventBus.registerHandler(UserLoginEvent.class, event -> {
            System.out.println("用户登录: " + event.getUsername());
            // 记录登录日志
            // 发送登录通知
            // 更新用户状态
        });
        
        GlobalEventBus.registerHandler(OrderCreatedEvent.class, event -> {
            System.out.println("订单创建: " + event.getOrderId() + ", 金额: " + event.getAmount());
            // 发送订单通知
            // 更新库存
            // 计算佣金
        });
        
        GlobalEventBus.registerHandler(OrderCreatedEvent.class, event -> {
            // 另一个处理器
            System.out.println("发送短信通知: 订单 " + event.getOrderId() + " 已创建");
        });
        
        // 发布事件
        GlobalEventBus.publishEvent(new UserLoginEvent("张三"));
        GlobalEventBus.publishEventAsync(new OrderCreatedEvent("ORD202401010001", 299.99));
        
        // 等待异步处理完成
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // 关闭
        GlobalEventBus.shutdown();
    }
}

总结

单例模式是设计模式中最常用也最容易被误用的模式。正确使用单例模式可以:

  1. 提高系统性能:通过资源共享减少资源消耗
  2. 保证数据一致性:通过统一入口管理状态
  3. 简化系统设计:通过减少重复代码降低复杂度

但需要特别注意:

  1. 线程安全:多线程环境下必须保证安全
  2. 序列化安全:防止序列化攻击
  3. 反射安全:防止反射攻击
  4. 测试友好:设计可测试的单例
  5. 合理使用:避免滥用单例导致系统僵化

在Spring等现代框架中,通常推荐使用IoC容器管理单例,而不是手动实现。但在框架底层、工具类、资源管理等场景,正确实现的单例模式仍然具有重要价值。