一、是什么
单例模式是一种创建型设计模式,保证一个类在整个应用生命周期中只有一个实例,并提供对该实例的全局访问点。
二、作用是什么
-
控制实例数量:限制系统中某个类只能有一个对象。
-
统一资源入口:提供全局统一的调用点,避免对象分散创建。
-
节省资源:避免重复构造昂贵对象(如数据库连接器)。
-
生命周期管理:由类自身控制对象的创建、初始化和销毁。
三、能够解决什么问题
-
重复创建导致的资源浪费
例如频繁创建连接池、线程池等重量级对象。
-
多个对象导致状态不一致
如多个日志管理器对象会造成日志写入位置混乱。
-
全局共享资源的访问冲突
如缓存对象在多个模块间需要统一访问。
-
需要一个中心调度器
如配置中心、任务调度器、消息中心等。
四、适用的场景
单例适用于保证"系统中某个类只有一个实例"的场景:
-
日志系统(LogManager)
-
配置管理器(ConfigManager)
-
线程池(ThreadPool)
-
数据库连接池(DataSource / ConnectionPool)
-
缓存组件(CacheManager)
-
全局注册表(Registry)
-
任务调度器(Scheduler)
-
控制中心(ControllerCenter)
五、特点
| 特点 | 说明 |
|---|---|
| ✅ 只有一个实例 | 全局唯一,由内部控制实例化 |
| ✅ 自行创建实例 | 禁止外部 new,只能通过 getInstance 获取 |
| ✅ 延迟加载可配置 | 饿汉(类加载时)或懒汉(第一次调用时) |
| ✅ 可支持线程安全 | 使用 synchronized、双检锁、静态内部类 |
| ✅ 全局访问点 | 任何地方可以 getInstance() |
| ⚠️ 破坏性风险 | 反射、序列化可能创建多个实例(可防御) |
| ⚠️ 隐式全局状态 | 滥用会降低可测试性与可维护性 |
六、编码实现
✅ 方案 1:懒汉式(线程不安全,不推荐)
java
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
✅ 方案 2:懒汉式 + 双重检查锁(DCL,推荐)
java
public class Singleton {
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;
}
}
特点:高性能 + 线程安全。
✅ 方案 3:静态内部类(最推荐,优雅)
java
public class Singleton {
private Singleton() {}
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
优势:
JVM 按需加载 Holder
线程安全
实现简单
✅ 方案 4:枚举单例(最安全)
java
public enum Singleton {
INSTANCE;
}
优点:天然防止反射和序列化破坏。
七、分析框架源码
Spring Bean 默认单例(Singleton Scope)
Spring 容器在启动时会创建单例 Bean,并存入:
java
DefaultSingletonBeanRegistry#singletonObjects
流程:
BeanDefinition 解析
实例化单例 Bean
放入 singletonObjects 缓存
每次 getBean 都直接返回缓存对象
核心代码(简化):
java
public Object getSingleton(String beanName) {
return this.singletonObjects.get(beanName);
}
ThreadPoolExecutor、LoggerFactory 等框架中也采用类似结构。