单例模式
# 单例模式
单例模式是最常用的设计模式之一,核心目标是保证一个类在整个程序生命周期中只有一个实例,并提供一个全局访问点来获取这个实例。
# 实际应用场景
- 数据库连接池
- 创建数据库连接(TCP 握手、认证)是非常耗时的操作,如果每次操作数据库都 new 一个连接池,会导致连接数爆炸、性能暴跌;单例能保证整个应用只有一个连接池,统一管理连接的创建、复用、销毁。
- 例如:Java 中的DruidDataSource、HikariCP连接池,默认都是单例模式实现,全局只初始化一次连接池配置。
- 缓存管理:
- 缓存需要全局唯一的实例,否则不同实例的缓存数据不一致,会出现 “读不到最新数据”、“重复缓存相同内容” 的问题;单例能统一缓存的增删改查逻辑。
- 例如Spring 中的CacheManager、Redis 的JedisPool/LettuceClient,都是单例模式 —— 整个应用只有一个缓存客户端实例,所有业务代码都通过这个实例操作缓存。
- 日志工具类
- 日志工具需要保证日志写入的顺序(比如按时间戳写入文件),如果多个日志实例同时写入一个文件,会出现日志错乱、内容重叠;单例能保证日志操作的串行化。
- 例如:Log4j、SLF4J、Python 的 logging 模块,默认都是单例模式 —— 全局只有一个日志器(Logger)实例,所有代码都通过这个实例输出日志。
# 创建方式
# 饿汉式
线程安全,简单但可能浪费资源
public class SingletonHungry {
// 1. 私有静态实例(类加载时直接初始化,唯一实例)
private static final SingletonHungry INSTANCE = new SingletonHungry();
// 2. 私有构造方法,禁止外部new
private SingletonHungry() {}
// 3. 公共静态方法,返回唯一实例
public static SingletonHungry getInstance() {
return INSTANCE;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 懒汉式
推荐:懒加载 + 线程安全 + 高性能
只有调用 getInstance() 时才创建实例(懒加载),但多线程环境下可能创建多个实例,需加锁。
public class SingletonDCL {
// 1. 私有静态实例,加volatile防止指令重排序
private static volatile SingletonDCL instance;
// 2. 私有构造方法
private SingletonDCL() {}
// 3. 双重检查锁
public static SingletonDCL getInstance() {
// 第一次检查:实例已存在则直接返回,避免加锁开销
if (instance == null) {
synchronized (SingletonDCL.class) {
// 第二次检查:防止多线程同时进入第一层检查后,重复创建实例
if (instance == null) {
instance = new SingletonDCL();
}
}
}
return instance;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 静态内部类(最优)
最优:懒加载 + 线程安全 + 无锁
利用 JVM 类加载机制保证线程安全,且只有调用 getInstance() 时才加载内部类、创建实例。
public class SingletonStaticInner {
// 1. 私有构造方法
private SingletonStaticInner() {}
// 2. 静态内部类(仅在被使用时加载)
private static class SingletonHolder {
private static final SingletonStaticInner INSTANCE = new SingletonStaticInner();
}
// 3. 公共静态方法
public static SingletonStaticInner getInstance() {
return SingletonHolder.INSTANCE;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
Last Updated: 2026/03/18, 21:53:17