6.设计模式-SINGLETON(单例)
一、模式定义与核心价值
单例模式是一种创建型设计模式,其核心目标是确保一个类仅有一个实例,并提供一个全局访问点以获取该实例。这一模式在以下场景中尤为重要:
- 资源控制:管理数据库连接、线程池、日志系统等共享资源,避免资源竞争
- 状态一致性:确保全局配置、缓存管理等场景中数据的一致性
- 性能优化:减少频繁创建/销毁高开销对象的系统损耗
核心哲学:通过私有化构造器和静态实例管理,实现对象生命周期的精确控制,在系统全生命周期中保持唯一性。
二、模式组成与UML类图
核心角色:
- Singleton(单例类):
-
- 私有构造函数(阻止外部实例化)
- 静态成员变量(保存唯一实例)
- 公共静态方法(提供全局访问入口)
- Client(客户端):通过
getInstance()方法获取单例对象
UML类图:
classDiagram
class Singleton {
-static instance: Singleton
-Singleton()
+static getInstance(): Singleton
+otherMethod()
}
Singleton --> Singleton : 依赖自身实例
Client --> Singleton : 通过getInstance()访问

三、代码实现与变体分析
1. 饿汉式(Eager Initialization)
public class Singleton {
// 类加载时即初始化实例
private static final Singleton INSTANCE = new Singleton();
private Singleton() {} // 私有构造器
public static Singleton getInstance() {
return INSTANCE;
}
}
特点:
- 线程安全(JVM保证类加载过程同步)
- 可能造成资源浪费(未使用时仍占用内存)
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;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 第一次检查
synchronized (Singleton.class) {
if (instance == null) { // 第二次检查
instance = new Singleton();
}
}
}
return instance;
}
}
特点:
- 结合延迟加载与线程安全
volatile关键字防止指令重排序
4. 枚举实现(Enum)
public enum Singleton {
INSTANCE;
public void execute() {
// 业务方法
}
}
特点:
- 天然防止反射攻击与序列化破坏
- 代码简洁,JVM保证单例性
5.静态内部类(Holder Pattern)
public class HolderSingleton {
private HolderSingleton() {}
private static class Holder {
private static final HolderSingleton INSTANCE = new HolderSingleton();
}
public static HolderSingleton getInstance() {
return Holder.INSTANCE;
}
}
优点:
- 延迟加载且线程安全(JVM保证内部类加载的线程互斥性)
- 无同步开销,性能优异
- 适用场景:需兼顾性能与延迟加载的通用场景(推荐首选方案
四、工业级源码应用
JDBC数据库连接
DriverManager通过静态方法管理数据库驱动,本质是单例思想的延伸
Connection conn = DriverManager.getConnection(url, user, password);
Spring框架
Bean默认单例作用域,通过ApplicationContext统一管理
@Service
public class UserService {
// 默认单例
}
Android系统服务
LayoutInflater等系统服务通过getSystemService()获取单例
LayoutInflater inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
智能合约开发
区块链中的全局配置合约通过注册表模式实现单例特性
contract SingletonRegistry {
mapping(bytes32 => address) private instances;
function getSingleton(bytes32 key) public view returns (address) {
return instances[key];
}
}
五、模式优劣与适用场景
优势:
- 内存优化:减少重复对象的内存占用
- 行为可控:统一管理共享资源访问
- 全局访问:简化跨组件调用流程
劣势:
- 违背单一职责原则(同时管理创建与业务)
- 单元测试困难(难以模拟替代实例)
- 多线程环境下需谨慎处理同步问题
适用场景:
- 需要严格管控资源访问(如数据库连接池)
- 全局配置管理(如系统参数、主题设置)
- 高频使用的工具类(如日志处理器)
- 跨组件状态共享(如购物车、用户会话)
六、设计决策建议
- 线程安全优先:优先选择枚举或饿汉式实现
- 延迟加载权衡:高并发场景推荐双重检查锁
- 防御性编程:防止反射攻击(通过构造函数抛出异常)
- 框架集成:结合Spring的
@Scope("singleton")注解管理生命周期9
总结
单例模式通过实例唯一性与全局访问点的设计哲学,成为管理共享资源的利器。在Java生态中,该模式已深度融入JDK、Spring等主流框架,并在区块链等新兴领域展现独特价值。开发者需根据具体场景选择合适实现,警惕多线程陷阱,方能充分发挥其设计优势。

浙公网安备 33010602011771号