Java基础:单例模式,Spring源码中有哪些单例模式

单例模式是一种常用的软件设计模式,其目的是确保一个类仅有一个实例,并提供一个全局访问点来获取这个唯一实例。在Java中,实现单例模式通常需要遵循以下几个关键原则:

  1. 私有化构造器:将类的构造器声明为private,以防止外部代码通过new操作符直接创建该类的实例。

  2. 静态工厂方法:提供一个静态方法(通常称为getInstance()),用于获取单例对象。这个方法负责检查是否已经创建过实例,如果尚未创建,则创建并保存;如果已存在,则直接返回该实例。

  3. 确保线程安全:在多线程环境中,必须确保单例对象的创建过程是线程安全的,即无论何时何地,无论多少个线程同时请求,都只会创建一个实例。

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

1. 饿汉式(静态常量)

优点:类加载时即初始化单例,线程安全,无同步开销。

缺点:如果单例实例很庞大或创建过程耗时,可能会导致类加载时较长的初始化时间,且即使从未使用该单例,也会占用内存。

public class SingletonEager {
    private static final SingletonEager INSTANCE = new SingletonEager();

    private SingletonEager() {}

    public static SingletonEager getInstance() {
        return INSTANCE;
    }
}

2. 懒汉式(线程不安全)

优点:延迟初始化,只有在首次调用getInstance()时才创建单例。

缺点:线程不安全,多线程环境下可能创建多个实例。

public class SingletonLazyUnsafe {
    private static SingletonLazyUnsafe instance;

    private SingletonLazyUnsafe() {}

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

3. 懒汉式(线程安全,同步方法)

优点:解决了线程安全问题。

缺点:每次调用getInstance()都会进行同步,造成不必要的性能损耗。

public class SingletonLazySynchronizedMethod {
    private static SingletonLazySynchronizedMethod instance;

    private SingletonLazySynchronizedMethod() {}

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

4. 双重检查锁定(DCL, Double-Checked Locking)

优点:既实现了延迟初始化,又保证了线程安全,且仅在初始化时加锁,性能较高。

缺点:依赖JVM正确实现内存模型,早期JVM版本可能存在DCL失效问题,但在现代JVM中已得到解决。

public class SingletonDCL {
    private volatile static SingletonDCL instance;

    private SingletonDCL() {}

    public static SingletonDCL getInstance() {
        if (instance == null) {
            synchronized (SingletonDCL.class) {
                if (instance == null) {
                    instance = new SingletonDCL();
                }
            }
        }
        return instance;
    }
}

5. 静态内部类

优点:利用类加载机制保证线程安全,延迟初始化,无同步开销。

缺点:相比其他实现方式,代码结构稍显复杂。

public class SingletonStaticInnerClass {
    private SingletonStaticInnerClass() {}

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

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

分析Spring源码中的单例模式及作用

Spring框架广泛使用了单例模式,尤其是在其核心组件BeanFactory中管理的bean实例。Spring默认将配置文件中定义的bean配置为单例模式,这意味着对于每个指定为单例的bean,Spring容器在整个应用程序生命周期中仅创建一次该bean的实例,并将其缓存起来,后续对该bean的所有请求都将返回相同的实例。

作用:

  1. 资源优化:对于重量级、高消耗资源的对象(如数据库连接、线程池等),通过单例模式限制实例数量,避免资源浪费。
  2. 一致性保证:对于需要保持全局唯一状态或共享状态的bean,单例模式确保所有客户端共享同一份实例,从而维持状态的一致性。
  3. 简化编程模型:开发者无需关心bean实例的创建、管理和销毁,只需关注业务逻辑,降低了代码耦合度。

由于Spring源码庞大且涉及众多模块,这里无法直接给出全部相关源码。但可以简述Spring如何实现单例模式:

Spring的DefaultListableBeanFactory类(或其他实现BeanFactory接口的类)是Spring IoC容器的核心实现,它维护了一个DefaultSingletonBeanRegistry(或类似实现SingletonBeanRegistry接口的类)来管理单例bean。当容器创建一个bean时,首先检查是否已经存在该bean的单例实例。如果存在,直接从缓存中返回;否则,按照bean定义创建新实例,并将其放入缓存中。

以下是一段简化版的伪代码,以说明Spring如何通过SingletonBeanRegistry来实现单例模式:

public interface BeanFactory {
    Object getBean(String beanName);
}

public interface SingletonBeanRegistry {
    Object getSingleton(String beanName);
    void registerSingleton(String beanName, Object singletonObject);
}

public class DefaultListableBeanFactory implements BeanFactory {
    private final SingletonBeanRegistry singletonRegistry;

    public Object getBean(String beanName) {
        return this.singletonRegistry.getSingleton(beanName);
    }
}

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();

    public Object getSingleton(String beanName) {
        return this.singletonObjects.get(beanName);
    }

    public void registerSingleton(String beanName, Object singletonObject) {
        this.singletonObjects.putIfAbsent(beanName, singletonObject);
    }
}

实际Spring源码中,DefaultSingletonBeanRegistry及其相关类还包含了许多额外逻辑,如处理循环依赖、bean的后置处理器、生命周期回调等。以上伪代码仅为了说明Spring如何通过一个注册表(registry)来管理单例bean的创建和缓存,确保整个应用中每个bean名称对应唯一实例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/566873.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器学习基础-PR\ROC\F1

1 1 、ROC曲线2 、PC曲线3、F14 、正负样本不均衡时怎么选择 1 、ROC曲线 就是TPR 与FPR 曲线 如图&#xff0c;就是根据阈值不同&#xff0c;我们看我们的二分类器的结果&#xff0c;根据结果算出TPR(真阳性)与FPR(假阳性)&#xff0c;最好的情况就是如图&#xff0c;我们的…

2024年三支一扶报名照上传要求很严格

2024年三支一扶报名照上传要求很严格

2024年最新版云开发cms开通步骤,开始开发微信小程序前的准备工作,认真看完奥!

小程序官方有改版了&#xff0c;搞得石头哥不得不紧急的再新出一版&#xff0c;教大家开通最新版的cms网页管理后台 一&#xff0c;技术选型和技术点 1&#xff0c;小程序前端 wxml css JavaScript MINA原生小程序框架 2&#xff0c;数据库 云开发 云数据库 云…

合合信息Embedding模型:引领中文文本向量化技术新高度

目录 &#x1f345;前言&#x1f353;赛事含金量&#x1f353;Embedding技术简介&#x1f353;Embedding在大模型中的价值&#x1f353;合合信息Embedding模型特点及优势&#x1f353;合合信息Embedding模型测试&#x1f353;技术突破&#x1f353;公司介绍 &#x1f345;总结 …

360在线翻译免费API

一、需求&#xff1a; 根据360在线翻译&#xff0c;获取免费API&#xff0c;并调用 二、主要步骤 1、请求 url url "https://fanyi.so.com/index/search" 2、传入信息 datas {"query": "桌子"} 3、请求头 headers {"pro": &…

Axure糖尿病健康管理APP原型 (知识科普/病友社区/远程医生会诊/购物商城/血糖监测/饮食监测)

作品概况 页面数量&#xff1a;共 50 页 源文件格式&#xff1a;rp格式&#xff0c;兼容 Axure RP 9/10&#xff0c;非程序软件无源代码 应用领域&#xff1a;医疗健康、慢病管理、糖尿病管理 作品特色 本作品为Axure糖尿病健康管理APP端原型图&#xff0c;设计规范内容清晰…

第54篇:创建Platform Designer系统

Q&#xff1a;本期我们开始使用Platform Designer工具创建带IP核的FPGA自定义硬件系统。 A&#xff1a;Platform Designer是集成在Quartus软件里的系统设计工具&#xff0c;名称随着Quartus的不断更新曾命名为SOPC Builder和Qsys。 使用Platform Designer可以添加Quartus已有自…

Aigtek高压放大器在电活性聚合物中的作用是什么

电活性聚合物是一类特殊类型的聚合物&#xff0c;其性质和形状可以受到外部电场的调控。这些聚合物在多个领域中有着广泛的应用&#xff0c;包括人工肌肉、电动液体透镜、柔性电子、生物医学传感器等。高压放大器在电活性聚合物的研究和应用中扮演着关键的角色&#xff0c;下面…

【Qt 学习笔记】Qt常用控件 | 显示类控件 | Calendar Widget的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 显示类控件 | Calendar Widget的使用及说明 文章编号&am…

C#-使用Harmony库实现DLL文件反射调用

一. Harmony工作原理 利用C#运行时Runtime的反射机制,动态加载dll中的方法,字段,属性,实现对DLL方法的重写和代码注入。 二. Harmony下载及安装 1.下载Harmony_lib库lib.harmony.2.3.3.nupkg 霸王•吕布 / CSharpHarmonyLib GitCodehttps://gitcode.net/qq_35829452/csharph…

南京邮电大学数学实验A答案 | 《MATLAB数学实验》第三版课后习题答案

数学实验A 本仓库收集了2024年我在学习《数学实验A》课程期间完成的作业。课程使用的教材为《MATLAB数学实验》第三版&#xff0c;作者为胡良剑和孙晓君教授。 这个资源库的建立初衷是为了帮助南京邮电大学的同学们在学习过程中有一个参考的依据&#xff0c;减少一些无端浪费…

【网络编程】UDP实现回显服务器

一.网络编程的基本术语. 客户端 客户端是为用户提供本地服务的程序&#xff0c;通常位于用户设备上。也称为用户端&#xff0c;是相对于服务器而言的。它主要指安装在用户设备上的程序&#xff0c;这些程序能够与服务器进行通信&#xff0c;从而获取服务或者执行特定功能。在…

虚拟机中安装的CentOS7的桌面右上角没有网络图标解决方案

问题描述 今天在打开CentOS7后&#xff0c;发现右上角的网络图标不见了&#xff0c;然后命令行访问百度也不通。然后上网查了一些解决方法。 原因分析及解决方案&#xff1a; 上网查了许多解决方法&#xff0c;其中一种成功解决了我的问题&#xff1b;我的是配置文件的问题。…

双链向表专题

1.链表的分类 链表的种类非常多组合起来就有 2 2 8种 链表说明&#xff1a; 虽然有这么多的链表的结构&#xff0c;但是我们实际中最常⽤还是两种结构&#xff1a; 单链表 和 双向带头循环链表 1. 无头单向⾮循环链表&#xff1a;结构简单&#xff0c;⼀般不会单独⽤来存数…

在linux系统中启动pycharm

1.找到pycharm的安装路径&#xff0c;一般在下载文件夹中 2.进入pycharm的安装路径&#xff0c;进入bin目录 3.右击&#xff0c;打开终端&#xff0c;输入./pycharm.sh

Linux系统中Nginx的使用

Nginx是一款开源的高性能、高可靠性的Web服务器和反向代理服务器。它在Linux系统中得到了广泛的应用&#xff0c;被用于构建高性能的Web应用和提供反向代理服务。下面将介绍Nginx在Linux系统中的使用以及一些常见的应用案例。 一、Nginx的安装和配置 安装Nginx 在Linux系统中…

2024深圳杯数学建模挑战赛B题:批量工件并行切割下料问题思路代码成品论文分析

更新完整代码和成品完整论文 《2024深圳杯&东三省数学建模思路代码成品论文》↓↓↓ https://www.yuque.com/u42168770/qv6z0d/zx70edxvbv7rheu7?singleDoc# 问题重述 深圳杯数学建模挑战赛2024B题&#xff1a;批量工件并行切割下料问题 板材切割下料是工程机械领域重要…

hyperf 三十一 极简DB组件

一 安装及配置 composer require hyperf/db php bin/hyperf.php vendor:publish hyperf/db 默认配置 config/autoload/db.php 如下&#xff0c;数据库支持多库配置&#xff0c;默认为 default。 配置项类型默认值备注driverstring无数据库引擎 支持 pdo 和 mysqlhoststringl…

python_django中小学家校互动系统vue_flask家校联系

实现了一个完整的家校互动系统&#xff0c;其中主要有作业信息模块、学校管理员模块、学生学籍模块、学生成绩模块、学科模块、系统新闻模块、系统公告模块、校内新闻模块、校内公告模块、用户表模块、token表模块、关于我们模块、收藏表模块、年级模块、家长模块、教师模块、互…

贪心算法练习day.1

理论基础 贪心算法是一种常见的解决优化问题的方法&#xff0c;其基本思想就是在问题的每个决策阶段&#xff0c;都选择当前看起来最优的选择&#xff0c;即贪心地做出局部的最优决策&#xff0c;以此得到全局的最优解&#xff0c;例如在十张面额不同的钞票&#xff0c;让我们…
最新文章