Skip to content

什么情况下需要使用单例模式

单例模式概述

  • 定义
  • 单例模式(Singleton Pattern)确保一个类只有一个实例,并提供全局访问点。
  • 实现
  • 私有构造器 + 静态实例(如双重检查锁)。

什么情况下需要使用单例模式

  1. 全局唯一资源管理:需要一个全局共享的实例。
  2. 控制并发访问:避免多实例冲突。
  3. 高资源开销对象:创建成本高,需复用。
  4. 配置或状态共享:多个模块共享一致数据。
  5. 替代全局变量:提供受控的全局访问。

核心点

  • 单例适用于需要唯一性、共享性和资源控制的场景。

1. 适用场景详解

(1) 全局唯一资源管理

  • 需求
  • 系统中某资源只能有一个实例,如线程池、数据库连接池。
  • 示例
  • 线程池管理:
public class ThreadPool {
    private static final ThreadPool instance = new ThreadPool();
    private ThreadPool() { /* 初始化线程池 */ }
    public static ThreadPool getInstance() { return instance; }
}
  • 场景
  • Java 的 Runtime 类(JVM 运行时环境)。

(2) 控制并发访问

  • 需求
  • 多线程访问共享资源,避免竞争或重复创建。
  • 示例
  • 日志管理器:
public class Logger {
    private static Logger instance;
    private Logger() {}
    public static synchronized Logger getInstance() {
        if (instance == null) instance = new Logger();
        return instance;
    }
    public void log(String msg) { System.out.println(msg); }
}
  • 场景
  • 避免多线程写日志冲突。

(3) 高资源开销对象

  • 需求
  • 对象创建耗时或占内存大,需单例复用。
  • 示例
  • 数据库连接:
public class DBConnection {
    private static DBConnection instance = new DBConnection();
    private Connection conn;
    private DBConnection() { conn = DriverManager.getConnection("url"); }
    public static DBConnection getInstance() { return instance; }
}
  • 场景
  • 频繁创建连接影响性能。

(4) 配置或状态共享

  • 需求
  • 系统多个部分需访问同一配置或状态。
  • 示例
  • 配置管理:
public class Config {
    private static Config instance = new Config();
    private Map<String, String> settings = new HashMap<>();
    private Config() { settings.put("key", "value"); }
    public static Config getInstance() { return instance; }
    public String get(String key) { return settings.get(key); }
}
  • 场景
  • 应用全局配置(如 Spring 的 ApplicationContext)。

(5) 替代全局变量

  • 需求
  • 避免全局变量的无序访问,提供封装和控制。
  • 示例
  • 计数器:
public class Counter {
    private static Counter instance = new Counter();
    private int count = 0;
    private Counter() {}
    public static Counter getInstance() { return instance; }
    public synchronized void increment() { count++; }
}
  • 场景
  • 统计访问次数。

2. 不适用单例的场景

  • 频繁创建销毁
  • 单例生命周期长,不适合临时对象。
  • 状态不共享
  • 每个实例需独立状态时用多例。
  • 测试困难
  • 单例全局状态难 Mock。

3. 单例模式的优缺点

优点

  • 节省资源,保证唯一性。
  • 简化访问,控制并发。

缺点

  • 单点故障风险。
  • 扩展性差(如需多实例)。

4. 延伸与面试角度

  • 与框架
  • Spring 默认 Bean 是单例。
  • 实现方式
  • 懒加载、饿汉式、枚举。
  • 实际应用
  • 日志、配置、连接池。
  • 面试点
  • 问“场景”时,提资源管理和并发。
  • 问“实现”时,提线程安全。

总结

单例模式适用于全局唯一资源、并发控制、高开销对象、共享状态和替代全局变量的场景,确保资源复用和一致性。面试时,可提具体例子(如日志器)或代码,展示理解深度。