Java中的设计模式:单例模式的深入探讨

news2025/5/31 13:32:07

单例模式的原理

单例模式的核心在于控制实例的数量。在Java中,类的实例化通常是由new关键字完成的。然而,单例模式通过将构造器私有化(private),阻止了外部通过new关键字直接创建类的实例。取而代之的是,单例类内部会自己创建一个唯一的实例,并通过一个静态方法(通常是getInstance())来提供对这个实例的访问。

这种设计模式的关键在于:

  1. 私有化构造器:防止外部通过new关键字创建实例。

  2. 内部创建实例:单例类内部负责创建唯一的实例。

  3. 提供全局访问点:通过一个静态方法提供对唯一实例的访问。

单例模式的实现方式

虽然单例模式的核心思想简单,但在实际实现中却有多种方式,每种方式都有其特点和适用场景。

饿汉式单例

饿汉式单例是最简单的实现方式。它在类加载时就创建了单例实例,这种方式的优点是线程安全,实现简单,但缺点是可能会造成资源浪费,因为实例在类加载时就被创建了,即使没有被使用也会占用内存。

懒汉式单例

懒汉式单例在第一次使用时才创建实例,这种方式的优点是延迟加载,只有在真正需要时才会创建实例,避免了资源浪费。然而,懒汉式单例需要考虑线程安全问题,否则可能会出现多个线程同时创建多个实例的情况。

双重校验锁单例

双重校验锁单例是在懒汉式的基础上进行优化的实现方式。它通过两次检查实例是否为null,避免了不必要的同步操作,提高了性能。这种方式既保证了线程安全,又避免了资源浪费,是懒汉式单例的一种改进版本。

静态内部类单例

静态内部类单例是一种优雅的实现方式。它利用了Java的类加载机制,只有在第一次使用内部类时才会加载单例实例,既保证了延迟加载,又避免了线程安全问题。这种方式的优点是实现简单,线程安全,且延迟加载。

枚举单例

枚举单例是一种非常简单且线程安全的实现方式。它利用了Java枚举的特性,确保只有一个实例。这种方式的优点是实现简单,线程安全,且可以防止反序列化和反射攻击。

单例模式的优缺点

优点

  1. 全局唯一性:单例模式确保了一个类在系统中只有一个实例,避免了多个实例可能带来的冲突和资源浪费。

  2. 全局访问点:通过单例模式,可以提供一个全局访问点,方便在系统中任何地方获取单例实例。

  3. 延迟加载:在懒汉式和双重校验锁等实现方式中,单例实例只有在第一次使用时才会被创建,避免了资源的提前占用。

缺点

  1. 违背单一职责原则:单例模式将实例的创建和管理职责集中在一个类中,可能会导致类的职责过重。

  2. 线程安全问题:在懒汉式实现中,需要考虑线程安全问题,否则可能会出现多个线程同时创建多个实例的情况。

  3. 难以测试:单例模式的类通常是不可变的,这使得单元测试变得困难。

单例模式的应用场景

单例模式在实际开发中有着广泛的应用,以下是一些常见的应用场景:

  1. 配置管理器:配置管理器通常需要在系统中全局访问,且只需要一个实例来管理配置信息。

  2. 线程池管理器:线程池管理器通常只需要一个实例来管理线程池,避免了线程池的重复创建和销毁。

  3. 日志记录器:日志记录器通常需要在系统中全局访问,且只需要一个实例来记录日志信息。

  4. 数据库连接池:数据库连接池通常只需要一个实例来管理数据库连接,避免了数据库连接的重复创建和销毁。

单例模式的注意事项

  1. 线程安全:在懒汉式实现中,需要考虑线程安全问题,确保在多线程环境下只有一个实例被创建。

  2. 序列化问题:如果单例类实现了Serializable接口,需要在类中提供一个readResolve方法,避免反序列化时创建多个实例。

  3. 反射问题:如果单例类的构造器是私有的,可以通过反射的方式调用构造器创建多个实例,需要在构造器中添加额外的判断逻辑来避免这种情况。

总结

单例模式是一种非常常用的设计模式,它在Java编程中有着广泛的应用。通过本文的介绍,我们了解了单例模式的原理、实现方式、优缺点、应用场景以及注意事项。在实际开发中,我们需要根据具体需求选择合适的单例模式实现方式,并注意线程安全、序列化和反射等问题,以确保单例模式的正确使用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《软件工程》第 13 章 - 软件维护

知识思维导图 13.1 软件维护与进化的概念 1. 核心概念 软件维护:软件交付使用后,为纠正错误、改善性能或其他属性而进行的修改过程软件进化:随着时间推移,软件系统为适应环境变化和用户需求而不断演变的过程 2. 维护类型&#…

2024 CKA模拟系统制作 | Step-By-Step | 12、创建多容器Pod

目录 免费获取题库配套 CKA_v1.31_模拟系统 一、题目 二、考点分析 1. 多容器 Pod 的理解 2. YAML 配置规范 3. 镜像版本控制 三、考点详细讲解 1. 多容器 Pod 的工作原理 2. 容器端口冲突处理 3. 资源隔离机制 四、实验环境搭建步骤 总结 免费获取题库配套 CKA_v…

python:selenium爬取网站信息

关注我,精彩不错过! 前言 使用python的requests模块还是存在很大的局限性,例如:只发一次请求;针对ajax动态加载的网页则无法获取数据等等问题。特此,本章节将通过selenium模拟浏览器来完成更高级的爬虫抓…

满天星之canvas实现【canvas】

展示 文章目录 展示Canvas 介绍【基础】简介兼容性关键特性注意事项应用场景:基本示例 满天星代码实现【重点】代码解释 全量代码【来吧,尽情复制吧少年】html引入JS代码 参考资源 Canvas 介绍【基础】 简介 Canvas是一个基于HTML5的绘图技术&#xff0…

【开源解析】基于PyQt5+Folium的谷歌地图应用开发:从入门到实战

🌐【开源解析】基于PyQt5Folium的谷歌地图应用开发:从入门到实战 🌈 个人主页:创客白泽 - CSDN博客 🔥 系列专栏:🐍《Python开源项目实战》 💡 热爱不止于代码,热情源自每…

在 Ubuntu 22.04 LTS 上离线安装 Docker

在 Ubuntu 22.04 LTS 上离线安装 Docker 一、准备工作 1.1 获取目标系统信息 在目标 Ubuntu 22.04 LTS 系统上,先执行以下命令确认架构信息: uname -m lsb_release -a一般返回如下信息: 1.2 需要一台可联网的机器 准备一台可以连接互联网…

python调用langchain实现RAG

一、安装langchain 安装依赖 python -m venv env.\env\Scripts\activatepip3 install langchainpip3 install langchain-corepip3 install langchain-openaipip3 install langchain-communitypip3 install dashscopepip3 install langchain_postgrespip3 install "psyc…

触控精灵 ADB运行模式填写电脑端IP教程

•ADB模式,如果你手机已经root则可以直接运行,无需安装电脑端。 •ADB模式,如果你手机没有root,那你可以windows电脑下载【极限投屏】软件,然后你的手机和电脑的网络要同一个wifi,然后把你电脑的ip地址填写…

uniapp|实现多端图片上传、拍照上传自定义插入水印内容及拖拽自定义水印位置,实现水印相机、图片下载保存等功能

本文以基础视角,详细讲解如何在uni-app中实现图片上传→水印动态编辑→图片下载的全流程功能。 目录 引言应用场景分析(社交媒体、内容保护、企业素材管理等)uniapp跨平台开发优势核心功能实现​图片上传模块多来源支持:相册选择(`uni.chooseImage`)与拍照(`sourceType:…

linux有效裁剪视频的方式(基于ffmpeg,不改变分辨率,帧率,视频质量,不需要三方软件)

就是在Linux上使用OBS Studio录制一个讲座或者其他视频,可能总有些时候会多录制一段时间,但是如果使用剪映或者PR这样的工具在导出的时候总需要烦恼导出的格式和参数,比如剪映就不支持mkv格式的导出,导出成mp4格式的视频就会变得很…

服务器密码安全运维解决新思路:凭据管理SMS+双因素SLA认证结合的方案

引言:云服务器安全成本困局 在云计算渗透率突破60%的今天,中小企业正面临严峻的安全悖论:某权威机构数据显示,72%的云上数据泄露事件源于凭据管理不当,而传统安全解决方案的采购成本往往超过中小企业年利润的8%。这种…

论文阅读笔记——In-Context Edit

ICEdit 论文阅读笔记 指令图像编辑现有方法的局限: 微调类方法(InstructPix2Pix、Emu Edit、 Ultra Edit):需要大规模数据和算力、精度高但效率低且泛化性低;免训练方法(Prompt-to-Prompt、 StableFlow&am…

【后端高阶面经:MongoDB篇】41、MongoDB 是怎么做到高可用的?

一、MongoDB高可用核心架构:副本集(Replica Set)设计 (一)副本集角色与拓扑结构 1. 三大核心角色 角色职责描述资源占用选举权重数据存储Primary唯一接收写请求的节点,将操作日志(Oplog&…

DMBOK对比知识点整理(4)

1.常见数据质量维度 常见数据质量维度(DMBOK-P353)质量维度

day12 leetcode-hot100-21(矩阵4)

240. 搜索二维矩阵 II - 力扣(LeetCode) 1.暴力法O(m*n) 思路:两层for循环即可。 2.二分查找O(m*logn) 思路:每行都用二分查找,因为每行都是排好序的 class Solution {public boolean searchMatrix(int[][] matrix, int targe…

提问:鲜羊奶是解决育儿Bug的补丁吗?

在育儿这个"系统工程"中,过度提醒就像冗余代码:"快写作业"(重复调用)、"多穿衣服"(异常捕获)、"别玩手机"(进程阻断)。羊大师技术育儿实验…

关于数据仓库、数据湖、数据平台、数据中台和湖仓一体的概念和区别

我们谈论数据中台之前, 我们也听到过数据平台、数据仓库、数据湖、湖仓一体的相关概念,它们都与数据有关系,但他们和数据中台有什么样的区别, 下面我们将围绕数据平台、数据仓库、数据湖和数据中台的区别进行介绍。 一、相关概念…

什么是可重组机器人?

可重组机器人是一种具有高度灵活性和适应性的新型机器人系统,能够根据不同任务需求,快速改变自身结构和功能。下面我从概念、结构、特点、应用领域、发展趋势等方面,为你详细介绍: 概念:可重组机器人是由多个标准化、模…

4、docker compose

1、介绍 Docker Compose 是 Docker 官方提供的容器编排工具,用于简化多容器应用的开发、部署和管理。它通过声明式配置文件(YAML格式)定义容器化应用的服务、网络、存储等组件及其依赖关系,使用户能够通过单一命令快速启动、停止…

SQL里几种JOIN连接

数据信息: 员工表EMP 部门表DEPT 一、INNER JOIN(内连接) 作用:只返回两个表中完全匹配的行,相当于取交集。 场景:查询「有部门的员工信息」。 示例: SELECT 员工.姓名, 部门.部门名称 FR…