文章摘要: 单例模式使用总结。
简介
简要说明
- 单例模式(Singleton Pattern)是一种创建型设计模式。
- 单例类只能有一个实例。
- 单例类必须自己创建自己的实例。
- 单例类必须给所有其他对象提供仅这唯一实例。
主要功能
- 控制实例的数量,确保全局只有一个实例。
- 提供全局访问点。
注意事项
- 线程安全:确保单例模式在多线程环境中正确实现,避免多个线程同时创建单例类的多个实例。
- 延迟加载:如果单例类在初始化时需要消耗大量资源,应考虑使用延迟加载(懒汉模式),以避免不必要的资源消耗。
- 序列化问题:如果单例类需要被序列化,需要确保反序列化时不会创建新的实例。
- 防止反射攻击:反射可以破坏单例模式,需要采取措施防止通过反射创建多个实例。
- 避免全局状态:单例模式可能导致全局状态,这在某些情况下可能导致代码难以测试和维护。
- 资源释放:单例类可能会长时间存在于系统中,需要确保适时释放其持有的资源,避免内存泄漏。
- 依赖注入:尽量使用依赖注入而非单例模式来提供实例,这样可以提高代码的灵活性和可测试性。
- 单例的范围:确定单例的范围,是进程级别的还是类加载器级别的,根据需求合理选择。
适用场景
- 资源共享:当系统中需要一个类来控制对某种资源的访问,确保资源不被重复创建,如数据库连接池、线程池、文件系统操作等。
- 全局配置:需要全局访问的配置对象,例如系统的配置信息。
- 全局控制:某些需要全局统一管理或调度的类,如日志管理器、全局唯一序列号生成器。
- 唯一序列号生成器:生成唯一序列号,确保系统内不会产生重复的序列号。
- 同步访问:需要同步访问的资源或服务,确保操作的原子性。
Java 8
案例 - 懒汉式的单例模式
public class Test {
// 私有、静态的变量
// 存储该类的实例化对象
// 确保外部获取到的是唯一的
private static Test test;
// 构造方法 - 私有
// 不允许外部通过构造方法创建该类的对象
private Test() {
}
// 对外提供获取该类对象的方法
// 静态、线程安全
public static synchronized Test getTest() {
// 判断该类创建的对象是否存在
if (test == null) {
// 创建对象,并赋值给成员变量中
test = new Test();
}
return test;
}
}
案例 - 饿汉式的单例模式
public class Test {
// 私有、静态的变量
// 存储该类的实例化对象
// 确保外部获取到的是唯一的
// 此处直接初始化,创建该类的实例对象
private static Test test = new Test();
// 构造方法 - 私有
// 不允许外部通过构造方法创建该类的对象
private Test() {
}
// 对外提供获取该类对象的方法
// 静态、没有线程安全
public static Test getTest() {
// 不需要再判断是否已经实例化,因为从一开始已经完成创建
return test;
}
}