# 单例模式:Java 实现与工程实践
# 一、模式价值与典型场景
在 Java 开发中,单例模式常用于解决以下核心问题:
- 资源全局唯一性:如数据库连接池(避免重复创建连接)
- 配置统一管理:确保系统配置一致性
- 设备驱动控制:如打印机任务队列管理
- 性能优化:减少重量级对象创建开销
# 二、单例模式演进之路
# 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 { }
|
注意点:
默认单例是非懒加载的
结合 @Lazy 实现延迟初始化
与 prototype 作用域的混合使用技巧
# 五、工程实践建议
优先选择枚举实现:除非需要继承其他类
谨慎使用 DCL:在 JDK5 + 环境中使用
防御性编程:至少添加反射防护
文档说明:在类头注明单例性质
依赖注入整合:结合 @Autowired 使用
# 六、反模式警示
1 2 3 4 5 6 7
| public class FakeSingleton { public static final FakeSingleton INSTANCE = new FakeSingleton(); public FakeSingleton() {} }
|