# 单例模式:Java 实现与工程实践

# 一、模式价值与典型场景

在 Java 开发中,单例模式常用于解决以下核心问题:

  1. 资源全局唯一性:如数据库连接池(避免重复创建连接)
  2. 配置统一管理:确保系统配置一致性
  3. 设备驱动控制:如打印机任务队列管理
  4. 性能优化:减少重量级对象创建开销

# 二、单例模式演进之路

# 2.1 基础实现(非线程安全)

1
2
3
4
5
6
7
8
9
10
11
12
public class BasicSingleton {
private static BasicSingleton instance;

private BasicSingleton() {}

public static BasicSingleton getInstance() {
if(instance == null) {
instance = new BasicSingleton();
}
return instance;
}
}

缺陷:多线程环境下可能创建多个实例

# 2.2 同步方法实现

1
2
3
4
5
6
7
8
9
10
11
12
public class SynchronizedSingleton {
private static SynchronizedSingleton instance;

private SynchronizedSingleton() {}

public static synchronized SynchronizedSingleton getInstance() {
if(instance == null) {
instance = new SynchronizedSingleton();
}
return instance;
}
}

代价:每次访问需要同步,性能下降约 100 倍(实测数据)

# 2.3 双重校验锁(DCL)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class DCLSingleton {
private static volatile DCLSingleton instance;

private DCLSingleton() {}

public static DCLSingleton getInstance() {
if(instance == null) { // 第一次检查
synchronized(DCLSingleton.class) {
if(instance == null) { // 第二次检查
instance = new DCLSingleton(); // 原子性操作
}
}
}
return instance;
}
}

关键点

  • volatile 防止指令重排序(JVM 层面)
  • 锁粒度优化使性能提升约 50 倍(对比同步方法)

# 2.4 静态内部类实现(最优懒加载)

1
2
3
4
5
6
7
8
9
10
11
public class InnerClassSingleton {
private InnerClassSingleton() {}

private static class Holder {
static final InnerClassSingleton INSTANCE = new InnerClassSingleton();
}

public static InnerClassSingleton getInstance() {
return Holder.INSTANCE;
}
}

优势

  • 利用类加载机制保证线程安全
  • 天然防御序列化 / 反射攻击
  • 延迟初始化

# 2.5 枚举实现(Effective Java 推荐)

1
2
3
4
5
6
7
public enum EnumSingleton {
INSTANCE;

public void businessMethod() {
// 业务方法
}
}

# 三、防御性编程实践

# 3.1 防止反射破坏

1
2
3
4
5
6
7
8
9
public class ReflectionProofSingleton {
private static final ReflectionProofSingleton instance = new ReflectionProofSingleton();

private ReflectionProofSingleton() {
if(instance != null) {
throw new IllegalStateException("Singleton already initialized");
}
}
}

# 3.2 防止序列化破坏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class SerializationSafeSingleton implements Serializable {
private static final long serialVersionUID = 1L;

private static class Holder {
static final SerializationSafeSingleton INSTANCE = new SerializationSafeSingleton();
}

public static SerializationSafeSingleton getInstance() {
return Holder.INSTANCE;
}

protected Object readResolve() {
return getInstance();
}
}

# 四、Spring 框架中的特殊实现

1
2
3
4
5
@Component
@Scope("singleton") // 默认值可省略
public class SpringSingleton {
// 由IoC容器管理的单例
}

注意点

  • 默认单例是非懒加载的

  • 结合 @Lazy 实现延迟初始化

  • 与 prototype 作用域的混合使用技巧

# 五、工程实践建议

  1. 优先选择枚举实现:除非需要继承其他类

  2. 谨慎使用 DCL:在 JDK5 + 环境中使用

  3. 防御性编程:至少添加反射防护

  4. 文档说明:在类头注明单例性质

  5. 依赖注入整合:结合 @Autowired 使用

# 六、反模式警示

1
2
3
4
5
6
7
// 错误示例:看似单例的伪实现
public class FakeSingleton {
public static final FakeSingleton INSTANCE = new FakeSingleton();

// 允许通过new创建实例
public FakeSingleton() {}
}