发布时间:2026/9/7 11:09:27
单例模式深度剖析:各种实现方式的优缺点对比 目录一、单例模式的定义和应用场景一定义及基本要点二应用场景二、饿汉式单例模式一基本代码展示分析二基本分析和建议三、懒汉式单例模式双重检查锁一基本代码展示分析二基本分析和建议四、静态内部类实现单例模式一基本代码展示分析二基本分析和建议五、注册式单例模式一枚举式单例模式代码及分析Effective Java推荐单例模式二容器式单例模式代码及分析适用于实例非常多的情况便于管理但是是非线程安全的六、总结参考书籍、文献和资料干货分享感谢您的阅读在软件设计中单例模式是一种极为常见且重要的设计模式它确保一个类只有一个实例并提供全局访问点。这一特性使得单例模式在很多场景下都能有效地保证资源的统一管理和减少内存的浪费尤其在诸如数据库连接池、线程池等资源管理的应用中发挥着至关重要的作用。然而尽管单例模式非常实用它的实现方式却并非一成不变。在不同的应用场景下我们可能需要根据实际需求选择不同的单例实现策略——从简单的饿汉式单例到需要懒加载的懒汉式再到结合了性能优化的静态内部类实现每种实现方式都有其优缺点适用于不同的情况。本篇文章将深入分析Java中的多种单例模式实现帮助你了解它们的优缺点并通过实际代码示例展示如何在实际项目中合理选择和应用这些模式。无论你是初学者还是有一定经验的开发者相信你都能从中找到提升代码设计质量和性能的宝贵经验。一、单例模式的定义和应用场景一定义及基本要点单例模式是指确保一个类在任何情况下都绝对只有一个实例并提供一个全局访问点。该模式有三个基本要点一是这个类只能有一个实例二是它必须自行创建这个实例三是它必须自行向整个系统提供这个实例。二应用场景应用场景J2EE中的ServlertContext、SerletContextConfig等、Spring框架应用中的ApplicationContext、数据库连接池等。二、饿汉式单例模式一基本代码展示分析/** * 描述饿汉式单例模式 * 优点没有任何锁执行效率高用户体验比懒汉式单例模式更好 * 缺点类加载的时候就初始化不管用不用都占内存空间 * 建议适用于单例模式较少的场景 * 如果我们在程序启动后一定会加载到类那么用饿汉模式实现的单例简单又实用 * 如果我们是写一些工具类则优先考虑使用懒汉模式可以避免提前被加载到内存中占用系统资源。 * * author yanfengzhang * date 2020-01-02 20:39 */ public class HungrySingleton { private final static HungrySingleton HUNGRY_SINGLETON new HungrySingleton(); private HungrySingleton() { } public static HungrySingleton getInstance() { return HUNGRY_SINGLETON; } }二基本分析和建议优点没有任何锁执行效率高用户体验比懒汉式单例模式更好缺点类加载的时候就初始化不管用不用都占内存空间建议适用于单例模式较少的场景如果我们在程序启动后一定会加载到类那么用饿汉模式实现的单例简单又实用如果我们是写一些工具类则优先考虑使用懒汉模式可以避免提前被加载到内存中占用系统资源。三、懒汉式单例模式双重检查锁一基本代码展示分析/** * 描述懒汉式单例模式---双重检查锁 * 相比单锁而言双重检查锁性能上虽然有提升但是依旧用到了synchronized关键字总归要上锁对程序性能还是存在一定的性能影响 * 不算最优--存在优化空间 * * 建议如果我们在程序启动后一定会加载到类那么用饿汉模式实现的单例简单又实用 * 如果我们是写一些工具类则优先考虑使用懒汉模式可以避免提前被加载到内存中占用系统资源。 * * author yanfengzhang * date 2020-01-02 20:53 */ public class LazyDoubleCheckSingleton { /** * volatile 关键字可以保证线程间变量的可见性还有一个作用就是阻止局部重排序的发生 */ private volatile static LazyDoubleCheckSingleton lazyDoubleCheckSingleton null; private LazyDoubleCheckSingleton() { } public static LazyDoubleCheckSingleton getInstance() { if (null lazyDoubleCheckSingleton) { synchronized (LazyDoubleCheckSingleton.class) { if (null lazyDoubleCheckSingleton) { lazyDoubleCheckSingleton new LazyDoubleCheckSingleton(); } } } return lazyDoubleCheckSingleton; } }二基本分析和建议相比单锁而言双重检查锁性能上虽然有提升但是依旧用到了synchronized关键字总归要上锁对程序性能还是存在一定的性能影响。注意里面volatile的使用建议如果我们在程序启动后一定会加载到类那么用饿汉模式实现的单例简单又实用如果我们是写一些工具类则优先考虑使用懒汉模式可以避免提前被加载到内存中占用系统资源。四、静态内部类实现单例模式一基本代码展示分析/** * 描述屏蔽饿汉式单例模式的内存浪费问题和双重检查锁中synchronized的性能问题 * 避免因为反射破坏单例 * * author yanfengzhang * date 2020-01-02 21:08 */ public class LazyInnerClassSingleton { /** * 使用LazyInnerClassSingleton的时候会先默认初始化换内部类 * 如果没有使用则内部类是不加载的 */ private LazyInnerClassSingleton() { /*为了避免反射破坏单例需要在构造方法中增加限制一旦出现多次重复创建直接抛出异常*/ if (null ! Lazyholder.LAZY_INNER_CLASS_SINGLETON) { throw new RuntimeException(创建LazyInnerClassSingleton异常不允许创建多个实例); } } /** * 每一个关键字都不是多余的static是为了使单例的空间共享保证这个方法不会被重写、重载 */ public static final LazyInnerClassSingleton getInstance() { /*在返回结果前一定会先加载内部类*/ return Lazyholder.LAZY_INNER_CLASS_SINGLETON; } /** * 默认不加载 */ private static class Lazyholder { private static final LazyInnerClassSingleton LAZY_INNER_CLASS_SINGLETON new LazyInnerClassSingleton(); } }二基本分析和建议屏蔽饿汉式单例模式的内存浪费问题和双重检查锁中synchronized的性能问题同时考虑避免因为反射破坏单例问题。相对而言性能最好五、注册式单例模式注册式单例模式/登记式单例模式将每个实例都登记到一个地方使用唯一的标识获取单例。注册单例模式有两种枚举式单例模式容器式单例模式一枚举式单例模式代码及分析Effective Java推荐单例模式/** * 描述注册式单例模式/登记式单例模式将每个实例都登记到一个地方使用唯一的标识获取单例。 * 注册单例模式有两种枚举式单例模式容器式单例模式 * 此为枚举式单例模式---Effective Java推荐单例模式 * * author yanfengzhang * date 2020-01-03 09:59 */ public enum EnumSingleton { /*枚举式单例模式*/ INSTANCE; private Object data; public Object getData() { return data; } public void setData(Object data) { this.data data; } public static EnumSingleton getInstance() { return INSTANCE; } }二容器式单例模式代码及分析适用于实例非常多的情况便于管理但是是非线程安全的/** * 描述注册式单例模式/登记式单例模式将每个实例都登记到一个地方使用唯一的标识获取单例。 * 注册单例模式有两种枚举式单例模式容器式单例模式 * 建议容器式单例模式适用于实例非常多的情况便于管理但是是非线程安全的。 * * author yanfengzhang * date 2020-01-03 10:51 */ public class ContainerSingleton { private ContainerSingleton() { } private static MapString, Object ioc new ConcurrentHashMap(); public static Object getBean(String className) { synchronized (ioc) { if (ioc.containsKey(className)) { return ioc.get(className); } Object obj null; try { obj Class.forName(className).newInstance(); ioc.put(className, obj); } catch (Exception e) { e.printStackTrace(); } return obj; } } }六、总结单例模式作为一种经典的设计模式在软件开发中扮演着重要的角色。它不仅能够保证系统中某一资源的唯一性还能提供全局访问点使得系统的资源管理更加高效和可靠。本文介绍了多种单例模式的实现方式包括饿汉式单例、懒汉式单例双重检查锁、静态内部类实现单例以及注册式单例模式枚举和容器式并对每种方式的优缺点进行了详细分析。在实际应用中选择合适的单例实现方式至关重要。如果你的应用程序中单例类的初始化开销较小且始终需要加载饿汉式单例可能是一个简单且高效的选择而在需要延迟初始化的场景下懒汉式单例或者静态内部类实现则能更好地节省资源。对于实例管理复杂的应用注册式单例模式通过枚举和容器化的方式提供了灵活的解决方案。尽管每种实现方式都有其优缺点开发者应根据具体的需求、性能要求以及系统的复杂度来选择合适的模式。通过理解和掌握单例模式的实现你不仅能提升程序的结构设计还能在实际开发中避免常见的资源浪费和性能瓶颈。希望本文的分析和代码示例能够帮助你更好地理解和应用单例模式提升你的编程技能和系统设计能力。参考书籍、文献和资料1.《Sring 5 核心原理与30个类手写实战》谭勇徳中国公信出版社2019.2.极客时间课程《Java性能调优实战》刘超2019.

相关新闻

2026/9/7 11:09:27

直击高频编程考点:动态规划经典算法题总结

目录 一、动态规划总结 (一)基本理解 (二)应用分析 二、相关高频笔试题目练习 (一)最大子序和(Maximum Subarray) (二)最长上升子序列(Longest Increasing Subsequence) (三)最长公共子序列(Longest Common Subsequence) (四)最大子数组乘积(Maximu…

2026/9/7 11:09:27

AI视频创作全流程实战:从提示词到短剧成片

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/7 12:09:35

加扰与解扰原理及工程实践:从LFSR到同步恢复的完整指南

简介:加扰与解扰是数字通信中改善信号质量与数据安全的关键环节。这一资源面向通信工程与FPGA开发学习者或相关工程师,聚焦基于VHDL的加解扰算法设计、Modelsim功能仿真及硬件板卡验证。压缩包共132个文件,约1.37MB,以vhd源码文件…

2026/9/7 12:09:35

AES密钥查找工具原理与内存转储分析实战

简介:这份开源工具面向安全分析与逆向工程场景,可帮助安全研究员、CTF选手在运行进程的内存中定位AES密钥,支持128位、192位与256位密钥。工具基于C实现,压缩包共10个文件,以.h头文件、.cpp源码及Visual Studio工程文件…

2026/9/7 12:09:35

Windows下CUDA开发环境完整搭建指南:解决版本兼容与安装陷阱

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/7 12:04:35

元器件采购平台怎么选?按预算分档的实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/7 0:47:43

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/7 0:14:19

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/7 0:14:17

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/7 0:03:36

基于YOLOv8和PyQt5的麦穗稻穗检测识别系统设计与实现

这次我们来看一个把目标检测算法和桌面端工具结合得很典型的项目:基于 YOLOv8 PyQt5 的麦穗稻穗检测识别系统。这个项目本身不是新概念,但它的价值在于落地形态很完整。YOLOv8 负责核心的麦穗稻穗目标检测,PyQt5 负责提供可视化的桌面交互界…

2026/9/7 0:03:36

UL 1642锂电池安全标准全解析:测试项目、认证流程与避坑指南

简介:UL 1642是锂电池安全领域的重要规范,本中文版资源适合锂电池制造商、检测机构工程师及产品认证相关人员阅读,用于理解电池在设计与制造层面的安全要求、测试方法与合规要点。资源共1个PDF文件,压缩包大小834KB,便…

2026/9/7 0:03:36

BS EN 13814-1-2019游乐设施安全标准:设计与制造核心要点解析

简介:BS EN 13814-1:2019是英国采纳欧洲标准EN 13814-1:2019的正式版本,由BSI标准出版,重点规定游乐设施和游乐设备在设计与制造环节的安全准则,与BS EN 13814-2:2019、BS EN 13814-3:2019共同取代旧版BS EN 13814:2004。该标准面…

2026/9/6 11:40:10

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/6 19:33:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/6 10:19:40

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…