单一示例设计模式 - 双重检查锁定单一示例模板
最编程
2024-10-01 07:18:30
...
- 代码
// 双重检查单例
public class SingletonDoubleCheckLazy {
// 1. 构造方法私有化
private SingletonDoubleCheckLazy() {
}
// 2. 单例对象,初始为null
private volatile static SingletonDoubleCheckLazy instance = null;
// 3. 提供全局访问点
public static SingletonDoubleCheckLazy getInstance() {
if (instance == null) { // 第一次检查
synchronized (SingletonDoubleCheckLazy.class) {
if (instance == null) { // 第二次检查
instance = new SingletonDoubleCheckLazy();
}
}
}
return instance;
}
}
- 优点
- 延迟加载:只有在首次请求时创建实例,节省了系统启动时的资源。
- 线程安全:通过同步内部创建逻辑,保证了多线程环境下的安全性。
- 高效:只在必要时进行同步,避免了每次获取实例时都需要同步所带来的性能损失。
- 缺点
- 复杂性:实现相对复杂,需要理解 Java 内存模型和 volatile 关键字的作用。
- 编译器优化问题:早期 JVM 存在指令重排序的问题,可能导致对象创建未完成就返回给调用者。现代 JVM 已经解决了这个问题,但仍需注意 volatile 的正确使用。
- 反序列化问题:如果对象可以被序列化,那么反序列化可能会创建新的实例,破坏单例性质。
- 使用场景
- 当单例对象创建成本较高,并且需要在多线程环境中保持线程安全。
- 当单例对象的创建时机不确定,且创建后需要频繁访问时。
- 在分布式环境中,如果需要全局唯一的单例对象。