当前位置: 首页 > news >正文

详细讲解什么是单例模式

        当谈到单例模式时,我们指的是一种设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。这种模式在软件开发中很常见,特别是需要控制资源访问、配置管理、日志记录器等情况下。

让我们用一个简单的例子来解释单例模式:

        假设有一个名为 Logger 的日志记录器类,我们希望确保系统中只有一个日志记录器实例,以便在整个应用程序中记录日志。

public class Logger {// 声明一个私有静态变量来保存单例实例private static Logger instance;// 私有构造函数,防止外部直接实例化该类private Logger() {// 这里可以进行初始化操作}// 公共静态方法来获取单例实例public static Logger getInstance() {// 如果实例不存在,则创建一个新实例if (instance == null) {instance = new Logger();}// 返回单例实例return instance;}public void log(String message) {// 记录日志的具体逻辑System.out.println(message);}
}

现在,让我们来理解上述代码:

  1. 私有静态变量 instance 这是用来保存单例实例的变量。它被声明为私有,因此其他类无法直接访问它。

  2. 私有构造函数: 构造函数被声明为私有,这意味着其他类无法通过 new 关键字直接实例化 Logger 类。

  3. getInstance() 方法: 这是获取 Logger 实例的静态方法。它首先检查实例是否已经存在,如果不存在,则创建一个新的实例并将其返回。如果实例已经存在,则直接返回现有的实例。

使用单例模式的示例代码如下:

public class Main {public static void main(String[] args) {// 获取 Logger 实例Logger logger1 = Logger.getInstance();Logger logger2 = Logger.getInstance();// 验证 logger1 和 logger2 是否是同一个实例System.out.println(logger1 == logger2); // 这里应该打印 true// 使用日志记录器记录信息logger1.log("This is a log message.");logger2.log("Another log message.");}
}

        在这个例子中,Logger 类只有一个实例,并且通过 getInstance() 方法进行访问。当我们尝试使用两个不同的变量 logger1logger2 获取实例时,实际上它们都引用了相同的实例,因此打印结果为 true。这确保了系统中只有一个 Logger 实例,并且任何地方使用日志记录器都在操作同一个实例。

        实际上,上面的例子展示的是最基本的单例模式,它是一种简单的懒汉式实现。懒汉式指的是在首次被调用时才创建实例。在这个例子中,当调用 getInstance() 方法时,会检查实例是否已经存在,如果不存在则创建一个新实例,否则返回现有实例。

        另一种常见的单例模式是饿汉式单例模式。饿汉式指的是在类加载时就创建实例,而不是在首次被调用时才创建。让我们来看一下饿汉式单例模式:

public class EagerSingleton {// 在类加载时就创建实例并进行初始化private static final EagerSingleton instance = new EagerSingleton();// 私有构造函数,防止外部直接实例化该类private EagerSingleton() {// 这里可以进行初始化操作}// 公共静态方法来获取单例实例public static EagerSingleton getInstance() {return instance;}public void someBusinessLogic() {// 进行一些业务逻辑操作}
}

在这个例子中:

  1. EagerSingleton 类有一个私有的、静态的、最终的实例变量 instance,它在类加载时就被创建和初始化。

  2. 构造函数被声明为私有,确保外部无法直接实例化该类。

  3. getInstance() 方法简单地返回预先创建的实例。

        饿汉式单例模式的优点是实现简单,并且在多线程环境下能够保持线程安全,因为实例在类加载时就已经创建。但缺点是如果该实例在整个程序运行期间未被使用,会造成资源浪费,因为它在类加载时就被创建了。

        懒汉式和饿汉式单例模式各有其适用的场景。懒汉式可以延迟实例化,只有在需要时才创建,而饿汉式则在程序启动时就创建,适用于实例始终需要被使用的情况。

        单例模式可以帮助我们确保全局只有一个特定类的实例存在,这对于需要共享相同资源或状态的情况非常有用。但需要注意,如果不恰当地使用单例模式,可能会导致全局状态的滥用和应用程序结构的混乱。

相关文章:

详细讲解什么是单例模式

当谈到单例模式时,我们指的是一种设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。这种模式在软件开发中很常见,特别是需要控制资源访问、配置管理、日志记录器等情况下。 让我们用一个简单的例子来解释单…...

在springBoot中同时使用mysql和MongoDB

在SpringBoot中非关系向数据库MongoDB和关系型数据库MySQL都可通过引入相关依赖并按照指定配置单独集成; mysql引入依赖: compile "org.springframework.boot:spring-boot-starter-web:1.5.18.RELEASE"compile "org.springframework.boot:spring-boot-start…...

2023.11.19 hadoop之MapReduce

目录 1.简介 2.分布式计算框架-Map Reduce 3.mapreduce的步骤 4.MapReduce底层原理 map阶段 shuffle阶段 reduce阶段 1.简介 Mapreduce是一个分布式运算程序的编程框架,是用户开发“基于hadoop的数据分析应用”的核心框架; Mapreduce核心功能是…...

力扣第841题 钥匙和房间 C++ DFS BFS 附Java代码

题目 841. 钥匙和房间 中等 相关标签 深度优先搜索 广度优先搜索 图 有 n 个房间,房间按从 0 到 n - 1 编号。最初,除 0 号房间外的其余所有房间都被锁住。你的目标是进入所有的房间。然而,你不能在没有获得钥匙的时候进入锁住的房间…...

React 中 react-i18next 切换语言( 项目国际化 )

背景 平时中会遇到需求,就是切换语言,语种等。其实总的来说都是用i18n来实现的 思路 首先在项目中安装i18n插件,然后将插件引入到项目,然后配置语言包(语言包需要你自己来进行配置,自己编写语言包&#xff…...

antd design 5 版本 文件上传

<UploadcustomRequest{customRequest}accept".csv" showUploadList{false}><Button icon{<UploadOutlined />}>上传 CSV 文件</Button></Upload> accept 代表限制的上传类型 也可设置 .excel // 文件上传 ( CSV ) const customReques…...

【如何学习Python自动化测试】—— 浏览器操作

4 、 浏览器操作 4.1 浏览器最大化 Webdriver 打开浏览器后&#xff0c;默认不是最大化&#xff0c;如果需要界面最大化&#xff0c;需要通过 maximize_window()方法来实现&#xff0c;代码如下&#xff1a; maximize_window()方法是Selenium WebDriver提供的一个方法&#xf…...

Python编程技巧 – 使用字典

Python编程技巧 – 使用字典 Python Programming Skills – Using Dictionary Dictionary, 即字典&#xff0c;这是Python语言的一种重要的数据结构&#xff1b;Python字典是以键&#xff08;key&#xff09;值(value)对为元素&#xff0c;来存储数据的集合。 前文提到Python列…...

el-tree 与table表格联动

html部分 <div class"org-left"><el-input v-model"filterText" placeholder"" size"default" /><el-tree ref"treeRef" class"filter-tree" :data"treeData" :props"defaultProp…...

Leetcode刷题详解——删除并获得点数

1. 题目链接&#xff1a;740. 删除并获得点数 2. 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;你可以对它进行一些操作。 每次操作中&#xff0c;选择任意一个 nums[i] &#xff0c;删除它并获得 nums[i] 的点数。之后&#xff0c;你必须删除 所有 等于 nums[i] …...

HTTP四种请求方式,状态码,请求和响应报文

1.get请求 一般用于获取数据请求参数在URL后面请求参数的大小有限制 2.post请求 一般用于修改数据提交的数据在请求体中提交数据的大小没有限制 3.put请求 一般用于添加数据 4.delete请求 一般用于删除数据 5.一次完整的http请求过程 域名解析&#xff1a;使用DNS协议…...

Python - Wave2lip 环境配置与 Wave2lip x GFP-GAN 实战 [超详细!]

一.引言 前面介绍了 GFP-GAN 的原理与应用&#xff0c;其用于优化图像画质。本文关注另外一个相关的项目 Wave2lip&#xff0c;其可以通过人物视频与自定义音频进行适配&#xff0c;改变视频中人物的嘴型与音频对应。 二.Wave2Lip 简介 Wave2lip 研究 lip-syncing 以达到视频…...

2311rust,1.31版本更新

1.31.0稳定版 Rust1.31可能是最激动人心的版本! 使用Cargo创建一个新项目: cargo new foo以下是Cargo.toml的内容: [package] name "foo" version "0.1.0" authors ["名字"] edition "2018" //版本. [dependencies]在[package]…...

文心一言-情感关怀之旅

如何让LLM更有温度。 应用介绍...

下厨房网站月度最佳栏目菜谱数据获取及分析PLus

目录 概要 源数据获取 写Python代码爬取数据 Scala介绍与数据处理 1.Sacla介绍 2.Scala数据处理流程 数据可视化 最终大屏效果 小结 概要 本文的主题是获取下厨房网站月度最佳栏目近十年数据&#xff0c;最终进行数据清洗、处理后生成所需的数据库表&#xff0c;最终进…...

buildadmin+tp8表格操作(5)自定义组装搜索的查询

有时候我们会自定义组装一些数据&#xff0c;发送给后端&#xff0c;让后端来进行筛选&#xff0c;这里有一个示例 const onComSearchIdEq () > {// 展开公共搜索baTable.table.showComSearch true/*** 公共搜索表单赋值* 范围搜索有两个输入框&#xff0c;输入框绑定变量…...

企业级固态硬盘如何稳定运行?永铭固液混合铝电解电容来帮忙

企业级 固态硬盘 永铭固液混合铝电解电容 企业级固态硬盘&#xff08;SSD&#xff09;主要应用于互联网、云服务、金融和电信等客户的数据中心&#xff0c;企业级SSD具备更快传输速度、更大单盘容量、更高使用寿命以及更高的可靠性要求。 企业级固态硬盘的运行要求—固液混合电…...

【MISRA C 2012】Rule 4.2 不应该使用三连符

1. 规则1.1 原文1.2 分类 2. 关键描述3. 代码实例 1. 规则 1.1 原文 Rule 4.2 Trigraphs should not be used Category Advisory Analysis Decidable, Single Translation Unit Applies to C90, C99 1.2 分类 规则4.2&#xff1a;不应该使用三连符 Advisory建议类规范。 2…...

spring boot加mybatis puls实现,在新增/修改时,对某些字段进行处理,使用的@TableField()

1.先说场景&#xff0c;在对mysql数据库表数据插入或者更新时都得记录时间和用户id 传统实现有点繁琐&#xff0c;这里还可以封装一下公共方法。 2.解决方法&#xff1a; 2.1&#xff1a;使用aop切面编程&#xff08;记录一下&#xff0c;有时间再攻克&#xff09;。 2.2&…...

如何构建风险矩阵?3大注意事项

风险矩阵法&#xff08;RMA&#xff09;是确定威胁优先级别的最有效工具之一&#xff0c;可以帮助项目团队识别和评估项目中的风险&#xff0c;帮助项目团队对风险进行排序&#xff0c;清晰地展示风险的可能性和严重性&#xff0c;为项目团队制定风险管理策略提供依据。 如果没…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG

TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码&#xff1a;HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...

大数据驱动企业决策智能化的路径与实践

&#x1f4dd;个人主页&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;数据驱动的企业竞争力重构 在这个瞬息万变的商业时代&#xff0c;“快者胜”的竞争逻辑愈发明显。企业如何在复杂环…...

高抗扰度汽车光耦合器的特性

晶台光电推出的125℃光耦合器系列产品&#xff08;包括KL357NU、KL3H7U和KL817U&#xff09;&#xff0c;专为高温环境下的汽车应用设计&#xff0c;具备以下核心优势和技术特点&#xff1a; 一、技术特性分析 高温稳定性 采用先进的LED技术和优化的IC设计&#xff0c;确保在…...