DeepSeek Java 单例模式详解

Java 单例模式详解

单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。## 单例模式的实现方式### 1. 饿汉式(Eager Initialization)javapublic class EagerSingleton { // 类加载时就创建实例 private static final EagerSingleton instance = new EagerSingleton(); // 私有构造函数,防止外部实例化 private EagerSingleton() { // 防止通过反射创建实例 if (instance != null) { throw new RuntimeException("单例模式不允许创建多个实例"); } } // 全局访问点 public static EagerSingleton getInstance() { return instance; }}优点 :线程安全,实现简单缺点 :类加载时就创建,可能造成资源浪费### 2. 懒汉式(Lazy Initialization)javapublic class LazySingleton { private static LazySingleton instance; private LazySingleton() {} // 线程不安全版本 public static LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; } // 线程安全版本 - 方法同步 public static synchronized LazySingleton getInstanceThreadSafe() { if (instance == null) { instance = new LazySingleton(); } return instance; }}缺点 :同步方法性能较差### 3. 双重检查锁定(Double-Checked Locking)javapublic class DoubleCheckedSingleton { // 使用volatile防止指令重排序 private static volatile DoubleCheckedSingleton instance; private DoubleCheckedSingleton() {} public static DoubleCheckedSingleton getInstance() { if (instance == null) { // 第一次检查 synchronized (DoubleCheckedSingleton.class) { if (instance == null) { // 第二次检查 instance = new DoubleCheckedSingleton(); } } } return instance; }}优点 :线程安全,性能较好注意 :必须使用volatile关键字### 4. 静态内部类(Static Inner Class)javapublic class InnerClassSingleton { private InnerClassSingleton() {} private static class SingletonHolder { private static final InnerClassSingleton INSTANCE = new InnerClassSingleton(); } public static InnerClassSingleton getInstance() { return SingletonHolder.INSTANCE; }}优点 :线程安全,懒加载,实现简单### 5. 枚举(Enum) - 推荐方式javapublic enum EnumSingleton { INSTANCE; // 可以添加方法 public void doSomething() { System.out.println("单例方法执行"); }}// 使用EnumSingleton.INSTANCE.doSomething();优点 :- 线程安全- 防止反射攻击- 防止反序列化创建新实例- 实现简单## 防止破坏单例的方法### 防止反射攻击javapublic class ReflectionSafeSingleton { private static volatile ReflectionSafeSingleton instance; private static boolean initialized = false; private ReflectionSafeSingleton() { synchronized (ReflectionSafeSingleton.class) { if (initialized) { throw new RuntimeException("单例模式不允许创建多个实例"); } initialized = true; } } public static ReflectionSafeSingleton getInstance() { if (instance == null) { synchronized (ReflectionSafeSingleton.class) { if (instance == null) { instance = new ReflectionSafeSingleton(); } } } return instance; }}### 防止反序列化javapublic class SerializationSafeSingleton implements Serializable { private static final long serialVersionUID = 1L; private static volatile SerializationSafeSingleton instance; private SerializationSafeSingleton() {} public static SerializationSafeSingleton getInstance() { if (instance == null) { synchronized (SerializationSafeSingleton.class) { if (instance == null) { instance = new SerializationSafeSingleton(); } } } return instance; } // 防止反序列化创建新实例 protected Object readResolve() { return getInstance(); }}## 完整示例javapublic class DatabaseConnection { private static volatile DatabaseConnection instance; private Connection connection; private DatabaseConnection() { // 初始化数据库连接 try { this.connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password"); } catch (SQLException e) { throw new RuntimeException("数据库连接失败", e); } } public static DatabaseConnection getInstance() { if (instance == null) { synchronized (DatabaseConnection.class) { if (instance == null) { instance = new DatabaseConnection(); } } } return instance; } public Connection getConnection() { return connection; } // 测试 public static void main(String[] args) { DatabaseConnection db1 = DatabaseConnection.getInstance(); DatabaseConnection db2 = DatabaseConnection.getInstance(); System.out.println(db1 == db2); // 输出: true System.out.println(db1.hashCode() == db2.hashCode()); // 输出: true }}## 总结| 实现方式 | 线程安全 | 懒加载 | 防止反射 | 防止反序列化 | 性能 ||---------|---------|--------|----------|-------------|------|| 饿汉式 | ✅ | ❌ | ❌ | ❌ | 高 || 懒汉式 | ❌/✅ | ✅ | ❌ | ❌ | 低 || 双重检查 | ✅ | ✅ | ❌ | ❌ | 中 || 静态内部类 | ✅ | ✅ | ❌ | ❌ | 高 || 枚举 | ✅ | ❌ | ✅ | ✅ | 高 |推荐使用枚举或静态内部类方式,它们实现简单且线程安全。如果需要防止反射和序列化破坏单例,枚举是最佳选择。

相关推荐
小羊没烦恼!1 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
俊昭喜喜里1 天前
java中的继承和多态的区别
java
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕1 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码1 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖1 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时1 天前
01-06-A-JVM排查实战详解
java·jvm
vipxieliang1 天前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot
ba_pi2 天前
mysql 查询所有表名并授权
java
ProcessOn官方账号2 天前
java函数式编程--入门基础
java·编程·函数式编程