2.单例模式

一、是什么

单例模式是一种创建型设计模式,保证一个类在整个应用生命周期中只有一个实例,并提供对该实例的全局访问点。

二、作用是什么

  • 控制实例数量:限制系统中某个类只能有一个对象。

  • 统一资源入口:提供全局统一的调用点,避免对象分散创建。

  • 节省资源:避免重复构造昂贵对象(如数据库连接器)。

  • 生命周期管理:由类自身控制对象的创建、初始化和销毁。

三、能够解决什么问题

  • 重复创建导致的资源浪费

    例如频繁创建连接池、线程池等重量级对象。

  • 多个对象导致状态不一致

    如多个日志管理器对象会造成日志写入位置混乱。

  • 全局共享资源的访问冲突

    如缓存对象在多个模块间需要统一访问。

  • 需要一个中心调度器

    如配置中心、任务调度器、消息中心等。

四、适用的场景

单例适用于保证"系统中某个类只有一个实例"的场景:

  1. 日志系统(LogManager)

  2. 配置管理器(ConfigManager)

  3. 线程池(ThreadPool)

  4. 数据库连接池(DataSource / ConnectionPool)

  5. 缓存组件(CacheManager)

  6. 全局注册表(Registry)

  7. 任务调度器(Scheduler)

  8. 控制中心(ControllerCenter)

五、特点

特点 说明
✅ 只有一个实例 全局唯一,由内部控制实例化
✅ 自行创建实例 禁止外部 new,只能通过 getInstance 获取
✅ 延迟加载可配置 饿汉(类加载时)或懒汉(第一次调用时)
✅ 可支持线程安全 使用 synchronized、双检锁、静态内部类
✅ 全局访问点 任何地方可以 getInstance()
⚠️ 破坏性风险 反射、序列化可能创建多个实例(可防御)
⚠️ 隐式全局状态 滥用会降低可测试性与可维护性

六、编码实现

✅ 方案 1:懒汉式(线程不安全,不推荐)

java 复制代码
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

✅ 方案 2:懒汉式 + 双重检查锁(DCL,推荐)

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;
    }
}

特点:高性能 + 线程安全。

✅ 方案 3:静态内部类(最推荐,优雅)

java 复制代码
public class Singleton {
    private Singleton() {}

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

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

优势:

JVM 按需加载 Holder

线程安全

实现简单

✅ 方案 4:枚举单例(最安全)

java 复制代码
public enum Singleton {
    INSTANCE;
}

优点:天然防止反射和序列化破坏。

七、分析框架源码

Spring Bean 默认单例(Singleton Scope)

Spring 容器在启动时会创建单例 Bean,并存入:

java 复制代码
DefaultSingletonBeanRegistry#singletonObjects

流程:

BeanDefinition 解析

实例化单例 Bean

放入 singletonObjects 缓存

每次 getBean 都直接返回缓存对象

核心代码(简化):

java 复制代码
public Object getSingleton(String beanName) {
    return this.singletonObjects.get(beanName);
}

ThreadPoolExecutor、LoggerFactory 等框架中也采用类似结构。

相关推荐
冰暮流星14 小时前
javascript如何实现将一个整数倒过来输出
开发语言·前端·javascript
Dylan的码园14 小时前
深入浅出Java排序:从基础算法到实战优化(下)
java·算法·排序算法
凤年徐14 小时前
C++ STL list 容器详解:使用与模拟实现
开发语言·c++·后端·list
中二病码农不会遇见C++学姐14 小时前
文明6 Mod制作核心组件关系解密:从XML到游戏的奇幻漂流
java·运维·服务器·游戏
我爱娃哈哈14 小时前
SpringBoot + ResponseBodyEmitter 实时异步流式推送:告别轮询,让数据推送更高效
java·spring boot·后端
白宇横流学长14 小时前
基于 SpringBoot 的足球俱乐部管理系统设计与实现【源码+文档】
java·spring boot·后端
lead520lyq14 小时前
Ethers.js发布合约及查询合约
开发语言·后端·区块链
电商API&Tina14 小时前
唯品会获得vip商品详情 API 返回值说明
java·大数据·开发语言·数据库·人工智能·spring
星辰徐哥14 小时前
易语言网络通信编程基础:HTTP/HTTPS/TCP/UDP实战开发
开发语言·http·https·udp·tcp·易语言
爱吃大芒果14 小时前
Flutter for OpenHarmony 实战: mango_shop 通用组件库的封装与跨端复用
开发语言·flutter·dart