Java——单例类设计模式

在Java中,单例类(Singleton Class) 是一种设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来获取该实例。单例模式通常用于管理共享资源(如数据库连接、线程池、配置管理器等),避免重复创建对象,节省系统资源。


1. 单例模式的核心特点

  1. 唯一实例:单例类只能有一个实例。
  2. 全局访问点:通过静态方法提供全局访问。
  3. 私有构造器 :防止外部通过new关键字创建实例。
  4. 线程安全:确保在多线程环境下也能正常工作。

2. 单例模式的实现方式

以下是几种常见的单例模式实现方式:

2.1 饿汉式(Eager Initialization)
  • 特点:在类加载时创建实例,线程安全。
  • 优点:实现简单,线程安全。
  • 缺点:如果实例未被使用,会造成资源浪费。
示例
java 复制代码
public class Singleton {
    // 在类加载时创建实例
    private static final Singleton INSTANCE = new Singleton();

    // 私有构造器
    private Singleton() {}

    // 全局访问点
    public static Singleton getInstance() {
        return INSTANCE;
    }
}

2.2 懒汉式(Lazy Initialization)
  • 特点 :在第一次调用getInstance()时创建实例。
  • 优点:延迟加载,节省资源。
  • 缺点:线程不安全,需要额外处理多线程问题。
示例(非线程安全)
java 复制代码
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton(); // 非线程安全
        }
        return instance;
    }
}
改进(线程安全)
java 复制代码
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton(); // 线程安全
        }
        return instance;
    }
}

2.3 双重检查锁(Double-Checked Locking)
  • 特点:在懒汉式的基础上,通过双重检查减少同步开销。
  • 优点:延迟加载,线程安全,性能较好。
  • 缺点:实现稍复杂。
示例
java 复制代码
public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) { // 第一次检查
            synchronized (Singleton.class) {
                if (instance == null) { // 第二次检查
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

2.4 静态内部类(Static Inner Class)
  • 特点:利用类加载机制保证线程安全,同时实现延迟加载。
  • 优点:线程安全,延迟加载,实现简单。
  • 缺点:无法传递参数。
示例
java 复制代码
public class Singleton {
    private Singleton() {}

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

2.5 枚举(Enum)
  • 特点:利用枚举的特性实现单例,线程安全,防止反射攻击。
  • 优点:线程安全,实现简单,防止反射和序列化破坏单例。
  • 缺点:不够灵活(无法延迟加载)。
示例
java 复制代码
public enum Singleton {
    INSTANCE;

    public void doSomething() {
        System.out.println("Singleton is working.");
    }
}

3. 单例模式的应用场景

  1. 资源共享
    • 例如数据库连接池、线程池等。
  2. 配置管理
    • 例如全局配置管理器。
  3. 日志记录
    • 例如日志记录器。
  4. 缓存
    • 例如全局缓存管理器。

4. 单例模式的注意事项

  1. 线程安全

    • 确保在多线程环境下单例类的唯一性。
  2. 反射攻击

    • 通过反射可以调用私有构造器创建新实例。枚举单例可以防止反射攻击。
  3. 序列化与反序列化

    • 反序列化时可能会创建新的实例。可以通过实现readResolve()方法解决。

    • 示例:

      java 复制代码
      protected Object readResolve() {
          return getInstance();
      }
  4. 延迟加载

    • 根据需求选择合适的实现方式(如懒汉式、静态内部类等)。

5. 单例模式的优缺点

优点
  1. 节省资源:避免重复创建对象。
  2. 全局访问:方便共享资源。
  3. 线程安全:通过合理实现可以保证线程安全。
缺点
  1. 扩展性差:单例类通常难以扩展。
  2. 测试困难:单例类的全局状态可能导致测试困难。
  3. 违反单一职责原则:单例类通常承担过多职责。

6. 总结

单例模式是Java中常用的设计模式,用于确保一个类只有一个实例,并提供全局访问点。根据具体需求,可以选择饿汉式、懒汉式、双重检查锁、静态内部类或枚举等实现方式。在实际开发中,需注意线程安全、反射攻击和序列化等问题。

相关推荐
二哈赛车手1 分钟前
新人笔记---实现简易版的rag的bm25检索(利用ES),以及RAG上传时的ES与向量数据库双写
java·数据库·笔记·spring·elasticsearch·ai
winner88814 分钟前
从零吃透C++命名空间、std、#include、string、vector
java·开发语言·c++
AI人工智能+电脑小能手13 分钟前
【大白话说Java面试题】【Java基础篇】第26题:Java的抽象类和接口有哪些区别
java·开发语言·面试
bzmK1DTbd22 分钟前
SOLID原则在Java中的实践:单一职责与开闭原则
java·开发语言·开闭原则
winner888127 分钟前
C++ 命名空间、虚函数、抽象类、protected 权限全套通俗易懂精讲(附与 Java 对比)
java·开发语言·c++
直奔標竿37 分钟前
Java开发者AI转型第二十五课!Spring AI 个人知识库实战(四)——RAG来源追溯落地,拒绝AI幻觉
java·开发语言·人工智能·spring boot·后端·spring
qq_589568101 小时前
java基础学习,案例练习,即时通讯
java·开发语言·学习
逸Y 仙X1 小时前
文章十九: ElasticSearch Full Text 全文本查询
java·大数据·数据库·elasticsearch·搜索引擎·全文检索
AI科技星1 小时前
全域数学·第卷:场计算机卷(场空间计算机)【乖乖数学】
java·开发语言·人工智能·算法·机器学习·数学建模·数据挖掘
0xDevNull1 小时前
Java泛型详解
java·开发语言·后端