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 }}## 总结| 实现方式 | 线程安全 | 懒加载 | 防止反射 | 防止反序列化 | 性能 ||---------|---------|--------|----------|-------------|------|| 饿汉式 | ✅ | ❌ | ❌ | ❌ | 高 || 懒汉式 | ❌/✅ | ✅ | ❌ | ❌ | 低 || 双重检查 | ✅ | ✅ | ❌ | ❌ | 中 || 静态内部类 | ✅ | ✅ | ❌ | ❌ | 高 || 枚举 | ✅ | ❌ | ✅ | ✅ | 高 |推荐使用枚举或静态内部类方式,它们实现简单且线程安全。如果需要防止反射和序列化破坏单例,枚举是最佳选择。

相关推荐
洛_尘2 小时前
数据结构--4:栈和队列
java·数据结构·算法
疯癫的老码农2 小时前
【小白入门docker】创建Spring Boot Hello World应用制作Docker镜像并运行
java·spring boot·分布式·docker·微服务
小刘不想改BUG2 小时前
Docker 部署微服务项目详细步骤
docker·微服务·容器
Mr.Entropy2 小时前
Hibernate批量查询方法全面解析
java·后端·hibernate
绝顶少年3 小时前
Spring 框架中 RestTemplate 的使用方法
java·后端·spring
小趴菜82273 小时前
安卓人机验证View
android·java·前端
观望过往3 小时前
【Java SE 运算符】全面解析与实践指南
java
没有bug.的程序员3 小时前
分布式架构初识:为什么需要分布式
java·分布式·架构·php
郑州光合科技余经理3 小时前
微服务架构:基于Spring Cloud ,构建同城生活服务平台
java·spring cloud·微服务·小程序·架构·uni-app