什么情况下需要使用单例模式
单例模式概述
- 定义:
- 单例模式(Singleton Pattern)确保一个类只有一个实例,并提供全局访问点。
- 实现:
- 私有构造器 + 静态实例(如双重检查锁)。
什么情况下需要使用单例模式
- 全局唯一资源管理:需要一个全局共享的实例。
- 控制并发访问:避免多实例冲突。
- 高资源开销对象:创建成本高,需复用。
- 配置或状态共享:多个模块共享一致数据。
- 替代全局变量:提供受控的全局访问。
核心点
- 单例适用于需要唯一性、共享性和资源控制的场景。
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 是单例。
- 实现方式:
- 懒加载、饿汉式、枚举。
- 实际应用:
- 日志、配置、连接池。
- 面试点:
- 问“场景”时,提资源管理和并发。
- 问“实现”时,提线程安全。
总结
单例模式适用于全局唯一资源、并发控制、高开销对象、共享状态和替代全局变量的场景,确保资源复用和一致性。面试时,可提具体例子(如日志器)或代码,展示理解深度。