单例模式(Singleton Pattern)是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。它通常用于需要控制资源访问或确保全局唯一性的场景。
核心特点:
单一实例:类只能创建一个实例。
全局访问:通过静态方法或属性提供对该实例的全局访问。
延迟初始化(可选):实例在首次使用时创建(懒汉式),或在类加载时创建(饿汉式)。
实现方式(以 Java 为例):
- 饿汉式(Eager Initialization)
类加载时就创建实例,线程安全但可能浪费资源。
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {} // 私有构造函数,防止外部实例化
public static Singleton getInstance() {
return instance;
}
}
2. 懒汉式(Lazy Initialization)
首次调用时创建实例,需注意线程安全。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() { // 加锁保证线程安全
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
3. 双检锁(Double-Checked Locking)
优化懒汉式,减少锁的开销。
public class Singleton {
private static volatile Singleton instance; // volatile 防止指令重排序
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
4. 静态内部类
结合饿汉式和懒汉式的优点,线程安全且延迟加载。
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
5. 枚举(最推荐)
天生线程安全,防止反序列化破坏单例,简洁高效。
public enum Singleton {
INSTANCE;
public void doSomething() {
// 业务逻辑
}
}
使用场景:
资源管理:如数据库连接池、线程池。
配置管理:全局配置类。
日志记录:统一日志管理器。
缓存:全局缓存实例。
优缺点:
优点:
减少资源消耗,确保全局唯一性。
提供统一的访问入口,便于管理。
缺点:
全局状态:可能导致隐式依赖,难以测试和维护。
扩展性差:难以继承或修改。
线程安全问题:懒汉式需额外处理并发。
注意事项:
防止反射攻击:通过私有构造函数抛出异常。
防止序列化破坏:实现 readResolve 方法或使用枚举。
避免在高并发场景下性能瓶颈(如懒汉式同步开销)。
单例模式简单但需谨慎使用,尤其在复杂系统中要考虑其全局性和测试性影响。