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 小时前
【JavaEE】网络初识
java
for_ever_love__3 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
我是人✓4 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
欣栀♡4 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
IT研究室4 小时前
最新计算机毕业设计选题推荐-基于spring boot的葡萄酒文化宣传网站-网站-文档指导-Java-springboot
java·spring boot·课程设计
慧都小项4 小时前
MyEclipse 中创建和测试 JAX-RS REST 接口:从项目配置到 REST Explorer
java·restful·myeclipse·jax-rs
Wang's Blog4 小时前
Java 项目实战: 交友项目 - 入门案例:编写 Dubbo 服务提供者
java·dubbo·交友
唠点键盘之外的4 小时前
27 存量系统接大模型:旁挂一个 AI 微服务,老架构一行不改
人工智能·微服务·架构
空空dream4 小时前
03 | 离线部署 FastAPI + Ollama(qwen2:0.5b):从 Docker 联调到 Kubernetes 验收
docker·ai·kubernetes·fastapi
秋饼5 小时前
Spring AI 2.0 结构化输出企业级实战:从 BeanOutputConverter 源码到生产级解析容错
java·ai·技术分享·后端开发