可能出现的反模式
- 懒汉式单例未考虑线程安全
- 问题描述:懒汉式单例在多线程环境下,如果多个线程同时调用
getInstance
方法,可能会创建多个实例,破坏单例模式。
- 示例代码:
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
- 饿汉式单例可能造成资源浪费
- 问题描述:饿汉式单例在类加载时就创建实例,即使该实例在整个应用生命周期中可能永远不会被使用,从而造成资源浪费。
- 示例代码:
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
- 双重检查锁定(DCL)的早期实现存在问题
- 问题描述:早期的双重检查锁定实现中,由于指令重排,可能导致在
instance
还未完全初始化时就被其他线程获取,从而引发空指针异常。
- 示例代码:
public class DoubleCheckedLockingSingleton {
private static DoubleCheckedLockingSingleton instance;
private DoubleCheckedLockingSingleton() {}
public static DoubleCheckedLockingSingleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckedLockingSingleton.class) {
if (instance == null) {
instance = new DoubleCheckedLockingSingleton();
}
}
}
return instance;
}
}
优化方式
- 懒汉式单例优化为线程安全
- 使用
synchronized
关键字:在 getInstance
方法上添加 synchronized
关键字,确保同一时间只有一个线程能进入方法创建实例。
- 示例代码:
public class ThreadSafeLazySingleton {
private static ThreadSafeLazySingleton instance;
private ThreadSafeLazySingleton() {}
public static synchronized ThreadSafeLazySingleton getInstance() {
if (instance == null) {
instance = new ThreadSafeLazySingleton();
}
return instance;
}
}
- **使用静态内部类**:利用类加载机制实现延迟加载且线程安全。
- **示例代码**:
public class StaticInnerClassSingleton {
private StaticInnerClassSingleton() {}
private static class SingletonHolder {
private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
}
public static StaticInnerClassSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
- 饿汉式单例优化资源浪费问题
- 改为静态内部类方式:如上述静态内部类单例实现,在需要使用实例时才加载内部类并创建实例。
- 双重检查锁定优化
- 使用
volatile
关键字:给 instance
变量添加 volatile
修饰符,防止指令重排。
- 示例代码:
public class SafeDoubleCheckedLockingSingleton {
private volatile static SafeDoubleCheckedLockingSingleton instance;
private SafeDoubleCheckedLockingSingleton() {}
public static SafeDoubleCheckedLockingSingleton getInstance() {
if (instance == null) {
synchronized (SafeDoubleCheckedLockingSingleton.class) {
if (instance == null) {
instance = new SafeDoubleCheckedLockingSingleton();
}
}
}
return instance;
}
}
- 使用枚举实现单例
- 描述:枚举类型天然线程安全,并且在类加载时就被初始化,同时防止反射和序列化破坏单例。
- 示例代码:
public enum EnumSingleton {
INSTANCE;
// 可以添加业务方法
public void doSomething() {
System.out.println("执行单例的业务方法");
}
}