单例模式 (Singleton Pattern)

发布于:2025-04-23 ⋅ 阅读:(122) ⋅ 点赞:(0)

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。

核心特点

  1. 唯一性:一个类只能有一个实例

  2. 全局访问:提供全局访问该实例的方式

  3. 延迟初始化:通常在第一次被请求时才创建实例(可选)

实现方式(Java示例)

1. 饿汉式(线程安全,类加载时初始化)

public class Singleton {
    // 类加载时就创建实例
    private static final Singleton instance = new Singleton();
    
    // 私有构造函数,防止外部实例化
    private Singleton() {}
    
    // 全局访问点
    public static Singleton getInstance() {
        return instance;
    }
}

优点:实现简单,线程安全
缺点:如果实例未被使用,会造成资源浪费

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

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

缺点:多线程环境下可能创建多个实例

3. 线程安全的懒汉式(同步方法)

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

优点:线程安全
缺点:每次获取实例都要同步,性能较差

4. 双重检查锁定(DCL,推荐方式)

public class Singleton {
    // volatile保证可见性和禁止指令重排序
    private static volatile Singleton instance;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

优点:线程安全,性能较好(只有第一次创建时需要同步)

5. 静态内部类实现(推荐方式)

public class Singleton {
    private Singleton() {}
    
    private static class Holder {
        private static final Singleton INSTANCE = new Singleton();
    }
    
    public static Singleton getInstance() {
        return Holder.INSTANCE;
    }
}

优点:线程安全,延迟加载,实现简单

6. 枚举实现(最佳方式,Java 1.5+)

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

优点:线程安全,防止反射攻击,防止反序列化重新创建对象
缺点:不够灵活(不能延迟初始化)

应用场景

  1. 配置管理:全局配置对象

  2. 日志记录器:应用只需要一个日志记录器实例

  3. 数据库连接池:避免频繁创建和销毁连接

  4. 线程池:管理应用中的线程资源

  5. 缓存系统:全局缓存访问点

注意事项

  1. 多线程环境:确保线程安全

  2. 序列化:如果需要序列化,应实现readResolve()方法防止反序列化创建新实例

  3. 反射攻击:可以通过反射调用私有构造函数,需要额外防护

  4. 单元测试:单例可能使测试变得困难(难以模拟替代)

  5. 全局状态:过度使用单例可能导致代码耦合度高

单例模式是设计模式中最简单但也是最容易误用的模式之一,应谨慎使用,避免滥用。


网站公告

今日签到

点亮在社区的每一天
去签到