01创建型设计模式——单例模式
一、单例模式简介
单例模式(Singleton Pattern)是一种创建型设计模式(GoF书中解释创建型设计模式:一种用来处理对象的创建过程的模式),单例模式是其中的一种,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。这个模式适用于那些需要一个全局唯一的对象来协调系统中的行为的情况。即在整个程序运行过程中,该类只存在一个对象(实例)。
GoF一书对单例模式的介绍

二、单例模式的用处
单例模式常见的使用场景
- 配置管理:全局配置管理器,确保配置只被加载一次并在全局范围内一致。
- 日志记录:全局日志记录器,确保所有日志信息被记录在一个地方。
- 线程池:全局线程池管理,避免多个线程池实例带来的资源浪费。
- 数据库连接池:全局数据库连接池,统一管理数据库连接的创建和销毁
单例模式的优点包括:
1. 确保全局唯一性
唯一性:单例模式确保一个类只有一个实例。这对于那些需要全局唯一的资源或管理类非常重要,例如配置管理器、日志记录器等。
全局访问:单例模式提供了一个全局访问点来获取这个唯一实例,使得所有代码都可以通过统一的方式来访问该实例。
2. 控制资源访问
资源管理:在某些情况下,某些资源(如数据库连接、线程池)只能由一个实例进行管理。使用单例模式可以有效地控制这些资源的创建和销毁,避免资源的重复创建和管理。
性能优化:通过避免创建多个实例,单例模式可以减少系统开销和资源浪费。
3. 简化接口
简化使用:由于只有一个实例,使用单例模式的类不需要考虑实例的创建和管理,使用时更简单直观。
一致性:可以保证对全局状态的一致性和统一管理,减少了不同实例间的状态不一致问题。
4. 延迟实例化
懒加载:通过懒汉式实现,单例模式可以实现延迟初始化(即实例在第一次使用时创建),从而提高系统启动速度并节省资源,直到确实需要实例时才创建它。
5. 避免多次实例化
避免浪费:有些对象的创建和初始化代价较高,使用单例模式可以避免重复创建这些对象,从而节省计算资源和时间。
三、单例模式的设计步骤
a)私有化构造函数
b)提供一个全局的静态方法(全局访问点)
c)在类中定义一个静态指针,指向该类的对象(静态指针由全局访问点获取)
四、单例模式的两种设计方法
1)懒汉式(Lazy Initialization)
这种设计方式只有在第一次使用时才会创建实例,这种方式的优点是延迟初始化。通常使用静态局部变量来实现线程安全的懒加载。
2)饿汉式(Eager Initialization)
在这种实现中,单例实例在程序启动时就被创建。也就是不管有没有被使用,只要程序运行就会创建该对象。这个实现简单,但如果单例实例的创建开销较大,可能会导致程序启动变慢,且可能会浪费资源。
懒汉式代码示例:
lazy.cpp
#include <iostream>//Lazy Initialization
class Singleton {
public:// 获取单例实例的公共方法static Singleton& getInstance() {static Singleton instance; // 静态局部变量,线程安全return instance;}// 禁止复制构造函数和赋值操作符Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;// 其他成员变量和方法void doWorking() const {std::cout<<"我是懒汉式创建型设计模式——单例模式! "<<std::endl;}private:Singleton() {} // 私有构造函数};// 使用示例
int main() {Singleton& singleton = Singleton::getInstance();Singleton* ptr = &Singleton::getInstance();//判断是否调用同一个对象if ( &singleton == ptr){std::cout<<"我们是同一个对象! "<<std::endl;}else{std::cout<<"我们是不同的对象! "<<std::endl;}//调用对象的方法singleton.doWorking();ptr->doWorking();return 0;
}
运行效果

饿汉式代码示例:
eager.cpp
#include <iostream>//Eager Initialization
class Singleton {
public:// 获取单例实例的公共方法static Singleton& getInstance() {return instance;}// 禁止复制构造函数和赋值操作符Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;// 其他成员变量和方法void doWorking() const {std::cout<<"我是饿汉式创建型设计模式——单例模式! "<<std::endl;}private:Singleton() {} // 私有构造函数static Singleton instance; // 声明静态成员};Singleton Singleton::instance; // 定义并初始化静态成员(只要程序运行就创建该实例)// 使用示例
int main() {Singleton& singleton = Singleton::getInstance();Singleton* ptr = &Singleton::getInstance();//判断是否调用同一个对象if ( &singleton == ptr){std::cout<<"我们是同一个对象! "<<std::endl;}else{std::cout<<"我们是不同的对象! "<<std::endl;}//调用对象的方法singleton.doWorking();ptr->doWorking();return 0;
}
运行效果

3)单例模式的线程安全问题
使用饿汉式方法创建单例模式,如果不使用静态局部变量,而是使用裸指针+判断的方式创建单例,很容易引发多线程的资源竞争问题。(线程在空闲状态下可以挂起)
使用双重检查锁定(Double-Checked Locking)来确保多线程环境下的单例创建的安全性。
示例代码:
doubleLock.cpp
#include <iostream>
#include <mutex>//线程安全的双重检查锁定
class Singleton {
public:static Singleton* getInstance() {if (!instance) {std::lock_guard<std::mutex> lock(mutex);if (!instance) {instance = new Singleton();}}return instance;}// 禁止复制构造函数和赋值操作符Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;// 其他成员变量和方法void doWorking() const {std::cout<<"我是懒汉式单例模式——我使用了双重检查锁定保证我的创建安全! "<<std::endl;}private:Singleton() {} // 私有构造函数//类中声明静态变量static Singleton* instance;static std::mutex mutex;};Singleton* Singleton::instance = nullptr; //定义并初始化指针为空
std::mutex Singleton::mutex; //定义并初始化互斥锁// 使用示例
int main() {Singleton* singleton = Singleton::getInstance();Singleton* ptr = Singleton::getInstance();//判断是否调用同一个对象if (singleton == ptr){std::cout<<"我们是同一个对象! "<<std::endl;}else{std::cout<<"我们是不同的对象! "<<std::endl;}//调用对象的方法singleton->doWorking();ptr->doWorking();return 0;
}
运行效果

23种设计模式中,单例模式是比较简单的一种,但是涉及到的知识面也是很多的,比如线程、互斥、同步等。 后面我还会继续讲解其他设计模式,敬请期待啦(¬‿¬)
相关文章:
01创建型设计模式——单例模式
一、单例模式简介 单例模式(Singleton Pattern)是一种创建型设计模式(GoF书中解释创建型设计模式:一种用来处理对象的创建过程的模式),单例模式是其中的一种,它确保一个类只有一个实例ÿ…...
图像分割(一)
一、概述 语义分割:是把每个像素都打上标签(这个像素点是人、树、背景等) 实例分割:不光要区别类别,还要区分类别中的每一个个体 损失函数:逐像素的交叉熵;样本均衡问题 MIOU指标:…...
C++ 新经典:设计模式 目录(先留框架,慢慢来~)
C 新经典:设计模式 C 新经典:设计模式 C 新经典:设计模式第1章 设计模式与软件开发思想、编程环境介绍第2章 模板方法模式第3章 工厂模式、原型模式、建造者模式第4章 策略模式第5章 观察者模式第6章 装饰模式第7章 单件模式第8章 外观模式第…...
go之命令行工具urfave-cli
一、urfave/cli urfave/cli 是一个声明性的、简单、快速且有趣的包,用于用 Go 构建命令行工具。 二、快速使用 2.1 引入依赖 go get github.com/urfave/cli/v2 2.2 demo package mainimport ("fmt""log""os""github.com/ur…...
四种应用层协议——MQTT、CoAP、WebSockets和HTTP——在工业物联网监控系统中的性能比较
目录 摘要(Abstract) 实验设置 实验结果 节选自《A Comparative Analysis of Application Layer Protocols within an Industrial Internet of Things Monitoring System》,作者是 Jurgen Aquilina、Peter Albert Xuereb、Emmanuel Francalanza、Jasmine Mallia …...
MySQL的脏读、不可重复读、幻读与隔离级别
脏读/不可重复读/幻读 脏读 脏读(Dirty Read)发生在一个事务读取了另一个事务尚未提交的数据。如果第二个事务失败并回滚,第一个事务读到的数据就是错误的。这意味着数据从一开始就是不稳定或者“脏”的。 举例 事务A读取了某条记录的值为X。事务B修改该记录的值…...
程序员前端开发者的AI绘画副业之路:在裁员危机中寻找新机遇
正文: 在这个充满变数的时代,作为一名前端开发者,我经历了行业的起伏,见证了裁员危机和中年失业危机的残酷。在这样的背景下,我开始了利用AI绘画作为副业的探索,不仅为了寻求经济上的稳定,更是为…...
Burp Suite的使用和文件上传漏洞靶场试验
第一步:分析如何利用漏洞,通过对代码的查阅发现,代码的逻辑是先上传后删除,意味着,我可以利用webshell.php文件在上传到删除之间的间隙,执行webshell.php的代码,给上级目录创建一个shell.php木马…...
如何在Ubuntu中安装deepin wine版的企业微信
如何在Ubuntu中安装deepin wine版的企业微信 运行如下一条命令将移植仓库添加到系统中 wget -O- https://deepin-wine.i-m.dev/setup.sh | sh自此以后,你可以像对待普通的软件包一样,使用apt-get系列命令进行各种应用安装、更新和卸载清理了。 安装企业…...
案例:Nginx + Tomcat集群(负载均衡 动静分离)
目录 案例 案例环境 案例步骤 部署Tomcat服务器 部署Nginx服务器 实现负载均衡和读写分离 日志控制 案例 案例环境 操作系统 IP 地址 角色 CentOS 192.168.10.101 Nginx服务器(调度器) CentOS 192.168.10.102 Tomcat服务器① CentOS 1…...
【密码学】密码协议的分类:②认证协议
密码协议的分类有很多种方式,这里我采取的是基于协议实现的目的来分类。可以将密码协议分成三类:认证协议、密钥建立协议、认证密钥建立协议。 一、认证协议是什么? 认证协议都在认证些什么东西呢?认证一般要认证三个东西&#x…...
异步编程(Promise详解)
目录 异步编程 回调函数 回调地狱 Promise 基本概念 Promise的特点 1.Promise是一种构造函数 2.Promise接收函数创建实例 3.Promise对象有三种状态 4.Promise状态转变不可逆 5.Promise 实例创建即执行 6.Promise可注册处理函数 7.Promise支持链式调用 Promise的静…...
DjangoORM注入分享
DjangoORM注入 简介 这篇文章中,分享一些关于django orm相关的技术积累和如果orm注入相关的安全问题讨论。 攻击效果同数据库注入 从Django-Orm开始 开发角度 Django ORM(Object-Relational Mapping)是Django框架中用于处理数…...
【HBZ分享】Redis各种类型的数据结构应用场景
String(字符串类型) 计数器: incr / decr, 比如商品库存,业务号的发号器业务数据key-value缓存, 缓存结果数据,提高网站性能,缓解DB压力分布式session会话, 集群环境下存储token鉴权信息分布式锁ÿ…...
anaconda创建并且配置pytorch(完整版)
📚博客主页:knighthood2001 ✨公众号:认知up吧 ** 🎃知识星球:【认知up吧|成长|副业】介绍** ❤️如遇文章付费,可先看看我公众号中是否发布免费文章❤️ 🙏笔者水平有限,欢迎各位大…...
高级java每日一道面试题-2024年8月10日-网络篇-你对跨域了解多少?
如果有遗漏,评论区告诉我进行补充 面试官: 你对跨域了解多少? 我回答: 跨域问题,即Cross-Origin Resource Sharing(CORS),是现代Web开发中一个非常重要的概念,涉及到浏览器的安全策略——同源策略(Same…...
AtCoder Beginner Contest 365 A~E
A.Leap Year(思维) 题意: 给你一个介于 1583 1583 1583和 2023 2023 2023之间的整数 Y Y Y。 求公历 Y Y Y年的天数。 在给定的范围内, Y Y Y年的天数如下: 如果 Y Y Y不是 4 4 4的倍数,则为 365 365 …...
多机部署, 负载均衡-LoadBalance
目录 1.负载均衡介绍 1.1问题描述 1.2什么是负载均衡 1.3负载均衡的一些实现 服务端负载均衡 客户端负载均衡 2.Spring Cloud LoadBalancer 2.1快速上手实现负载均衡 2.2负载均衡策略 自定义负载均衡策略 3.服务部署(Linux) 3.1服务构建打包…...
(回溯) LeetCode 78. 子集
原题链接 一. 题目描述 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的 子集 (幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入:nums [1,2,3] 输出&…...
DQL数据查询语言(多表处理)—/—<7>
一、多表处理 当前有两个表,一个是学生表student,一个是分数表score student表字段名表示如下(共1000条数据): score表字段表示如下(共6000条数据): 1、求每个学生的总分 SELECT …...
幻兽帕鲁存档迁移完全手册:告别数据丢失的终极解决方案
幻兽帕鲁存档迁移完全手册:告别数据丢失的终极解决方案 【免费下载链接】palworld-host-save-fix 项目地址: https://gitcode.com/gh_mirrors/pa/palworld-host-save-fix 你是否曾在更换幻兽帕鲁服务器时,眼睁睁看着自己辛苦培养的角色数据消失无…...
开源工具Cursor Free VIP:突破开发效率瓶颈的技术突破
开源工具Cursor Free VIP:突破开发效率瓶颈的技术突破 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your tri…...
避坑指南:深度相机与RGB相机标定中的5个常见错误
避坑指南:深度相机与RGB相机标定中的5个常见错误 在三维重建和增强现实开发中,深度相机与RGB相机的联合标定是基础却极易出错的关键环节。许多开发者投入大量时间调试标定结果,却因忽视了一些看似简单的细节而功亏一篑。本文将揭示五个最常被…...
英雄联盟玩家的终极效率工具:League-Toolkit 完整指南
英雄联盟玩家的终极效率工具:League-Toolkit 完整指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 还在为错过匹配确认而烦恼&a…...
BGE-Large-Zh前沿探索:量子计算语义编码实验
BGE-Large-Zh前沿探索:量子计算语义编码实验 引言 量子计算正在重新定义计算的边界,而自然语言处理作为人工智能的核心领域,也迎来了与量子技术融合的历史性机遇。我们进行了一项创新实验:将BGE-Large-Zh这一强大的语义编码模型…...
M2LOrder模型Typora写作辅助插件开发:实时监测文章情感基调
M2LOrder模型Typora写作辅助插件开发:实时监测文章情感基调 不知道你有没有过这样的经历:写了一篇技术文章,自己读起来总觉得哪里不对劲,但又说不出来具体问题。或者写产品文案时,明明想表达积极向上的情绪࿰…...
React Native Keyboard Controller部署指南:生产环境最佳配置
React Native Keyboard Controller部署指南:生产环境最佳配置 【免费下载链接】react-native-keyboard-controller Keyboard manager which works in identical way on both iOS and Android 项目地址: https://gitcode.com/gh_mirrors/re/react-native-keyboard-…...
终极指南:Lottie动画版本管理的5个专业技巧
终极指南:Lottie动画版本管理的5个专业技巧 【免费下载链接】lottie Lottie documentation for http://airbnb.io/lottie. 项目地址: https://gitcode.com/gh_mirrors/lo/lottie Lottie是Airbnb开发的开源动画库,它能让开发者轻松地在移动应用和网…...
Tencent Hunyuan3D-1.0学术合作机会:腾讯混元团队的研究方向与合作模式
Tencent Hunyuan3D-1.0学术合作机会:腾讯混元团队的研究方向与合作模式 【免费下载链接】Hunyuan3D-1 腾讯开源的Hunyuan3D-1项目,创新提出两阶段3D生成方法,实现快速、高质量的文本到3D和图像到3D转换,融合Hunyuan-DiT模型&#…...
5. 大模型核心基础概念(三):模型量化、蒸馏、微调的核心逻辑(通俗解读)
001、开篇:为什么大模型需要“瘦身”与“调教”?——量化、蒸馏、微调的必要性 上周在产线调试一个端侧部署的视觉模型,设备跑着跑着就内存溢出了。同事盯着日志问我:“模型在服务器上明明跑得好好的,怎么一到嵌入式板子上就崩了?” 我看了眼那 2GB 的 RAM 和板载的 8GB …...
