单例模式---线程安全实现
文章目录
- 1.单例模式的特点😊
- 2.单例模式两种实现🤣🤗😊
- 2.1 饿汉式
- 2.2 懒汉式
- 3.传统单例模式的线程安全问题
- 4.解决方法
- 4.1静态局部变量
- 4.2加锁
- 4.3双重检查锁(DCL)
- 4.4pthread_once
1.单例模式的特点😊
1.全局只有一个类的static实例存在;
2.不允许直接实例化,构造函数为私有的,只通过一个类的静态方法获取该实例;
2.单例模式两种实现🤣🤗😊
2.1 饿汉式
饿汉式是在类加载的时候就会创造实例,会造成资源的浪费。 具体:内部先定义并初始化好了一个静态实例。获取方法中直接返回实例。
特点:线程安全,会造成资源浪费
实现:
class Singleton {
private:static Singleton instance;// 私有构造函数,防止类外实例化对象Singleton() {}public:// 获取实例的静态方法static Singleton& getInstance() {return instance;}// 其他成员函数void doSomething() {// do something}
};// 静态成员变量需要在类外初始化
Singleton Singleton::instance;int main() {// 获取单例对象实例Singleton& singleton = Singleton::getInstance();// 调用单例对象的方法singleton.doSomething();return 0;
}
2.2 懒汉式
懒汉式是在需要时才创建实例,通过获取实例方法获取实例。
具体:内部定义一个静态实例,获取方法中判断实例是否为空,空则初始化实例;否则返回该实例
特点:避免资源浪费,造成线程安全问题。
实现
class Singleton {
private:// 静态成员变量,用于保存单例实例static Singleton* instance;// 构造函数私有化,防止外部创建实例Singleton() {}public:// 静态成员函数,用于获取单例实例static Singleton* getInstance() {// 判断实例是否为空,如果为空则创建实例if (instance == nullptr) {instance = new Singleton();}return instance;}// 删除拷贝构造函数和拷贝赋值运算符,防止被复制Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;
};Singleton* Singleton::instance = nullptr; // 初始化静态成员变量int main() {// 获取单例实例Singleton* singleton1 = Singleton::getInstance();Singleton* singleton2 = Singleton::getInstance();// 判断两个实例是否相同if (singleton1 == singleton2) {cout << "两个实例相同" << endl;} else {cout << "两个实例不相同" << endl;}return 0;
}
3.传统单例模式的线程安全问题
饿汉式是线程安全的,懒汉式不是
当多线程执行getInstance时候,如果线程A判断当前实例为空,线程B正好判断到也为空,就会申请资源;当线程A恢复了后,继续执行,也会申请内存空间;就会出现两个实例,这就会出现问题;
4.解决方法
4.1静态局部变量
class Singleton {
private:Singleton() {}public:static Singleton* getInstance() {static Singleton instance;return &instance;}
};
4.2加锁
class Singleton {
private:// 静态成员变量,用于保存单例实例static Singleton* instance;// 构造函数私有化,防止外部创建实例Singleton() {}public:// 静态成员函数,用于获取单例实例static Singleton* getInstance() {// 判断实例是否为空,如果为空则创建实例Mutexlock lock(mutex);//加锁if (instance == nullptr) {instance = new Singleton();}return instance;}// 删除拷贝构造函数和拷贝赋值运算符,防止被复制Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;
};Singleton* Singleton::instance = nullptr; // 初始化静态成员变量int main() {// 获取单例实例Singleton* singleton1 = Singleton::getInstance();Singleton* singleton2 = Singleton::getInstance();// 判断两个实例是否相同if (singleton1 == singleton2) {cout << "两个实例相同" << endl;} else {cout << "两个实例不相同" << endl;}return 0;
}
4.3双重检查锁(DCL)
class Singleton {
private:// 静态成员变量,用于保存单例实例static Singleton* instance;// 构造函数私有化,防止外部创建实例Singleton() {}public:// 静态成员函数,用于获取单例实例static Singleton* getInstance() {// 判断实例是否为空,如果为空则创建实例if (instance == nullptr) {Mutexlock lock(mutex);if(instance==nullptr)instance = new Singleton();}return instance;}// 删除拷贝构造函数和拷贝赋值运算符,防止被复制Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;
};Singleton* Singleton::instance = nullptr; // 初始化静态成员变量int main() {// 获取单例实例Singleton* singleton1 = Singleton::getInstance();Singleton* singleton2 = Singleton::getInstance();// 判断两个实例是否相同if (singleton1 == singleton2) {cout << "两个实例相同" << endl;} else {cout << "两个实例不相同" << endl;}return 0;
}
4.4pthread_once
#include<iostream>
class singleton{
public:
static singleton& getinstance()
{
pthread_once(&ponce,init);//保证该函数只被执行一次
return instance;
}
private:
static void init()
{
instance=new singleton();
}
singleton(){}
~singleton(){}
static pthread_once_t ponce;
static singleton* instance;
};
singleton::ponce=PTHREAD_ONCE_INIT;
singleton::instance=nullptr;
相关文章:
单例模式---线程安全实现
文章目录 1.单例模式的特点😊2.单例模式两种实现🤣🤗😊2.1 饿汉式2.2 懒汉式 3.传统单例模式的线程安全问题4.解决方法4.1静态局部变量4.2加锁4.3双重检查锁(DCL)4.4pthread_once 1.单例模式的特点…...
Agent技术在现代软件开发与应用中的探索
一、引言 随着计算机科学的快速发展,Agent技术作为人工智能和分布式计算领域的重要分支,已经渗透到软件开发的各个方面。Agent技术通过赋予软件实体自主性和交互性,使得软件系统能够更加智能、灵活地响应环境变化和用户需求。本文将对Agent技…...
c语言中extern定义和引用其他文件的变量,(sublime text)单独一个文件编译不会成功
关键字extern的作用 这个很常见的都知道是定义一个外部变量或函数,但并不是简单的建立两个文件,然后在用extern 定义在另一个非最初定义变量的文件里 区分文件和编译运行的文件 例如,一个文件夹里有文件a.c和文件b.c,在sublime text中直接…...
时序数据中的孤立野点、异常值识别及处理方法
目录 参考资料 对时序数据做差分; 参考资料 [1] 离群点(孤立点、异常值)检测方法 2017.6;...
JetBrains PyCharm 2024 mac/win版编程艺术,智慧新篇
JetBrains PyCharm 2024是一款功能强大的Python集成开发环境(IDE),专为提升开发者的编程效率和体验而设计。这款IDE不仅继承了前代版本的优秀特性,还在多个方面进行了创新和改进,为Python开发者带来了全新的工作体验。 JetBrains PyCharm 20…...
MCU解决800V电动汽车牵引逆变器的常见设计挑战的3种方式
电动汽车 (EV) 牵引逆变器是电动汽车的。它将高压电池的直流电转换为多相(通常为三相)交流电以驱动牵引电机,并控制制动产生的能量再生。电动汽车电子产品正在从 400V 转向 800V 架构,这有望实现: 快速充电 – 在相同…...
《逆向投资 邓普顿的长赢投资法》
接下来跟大家一起学习《逆向投资 邓普顿的长赢投资法》。邓普顿被誉为20世纪最伟大的选股人之一,我非常确信林奇在他的《战胜华尔街》里也提到了邓普顿,可惜实在想不起来林奇是怎么形容邓普顿的。 邓普顿拥有70多年的投资生涯,在他晚年时曾总…...
C++中main函数的参数、返回值分别什么意思?main函数返回值跟普通函数返回值一样吗?
在C中,main函数是程序的入口点,即程序开始执行的地方。main函数可以有两种形式的签名(signature): 标准的main函数,不接受任何参数,也不返回任何值: int main() {// 代码... }带有参…...
Java程序员学习Go开发Higress的WASM插件
Java程序员学习Go开发Higress的WASM插件 契机 ⚙ 今年天池大赛有higress相关挑战,研究一下。之前没搞过go,踩了很多坑,最主要的就是tinygo打包,多方寻求解决无果,结论是tinygo0.32go1.19无法在macos arm架构下打包。…...
Python入门-基本数据类型-数字类型
数字类型是指表示数字或者数值的数据类型。在Python语言中,数字类型有整型(int)、 浮点型(float)、复数型(complex),对应数学中的整数、小数和复数,此外还有一种特殊 的整型,即布尔型(bool)。本节将对这4种数字类型进行详细介绍。…...
小程序web-view无法打开该页面的解决方法
问题:开发者工具可以正常打开,正式上线版小程序使用 web-view 组件测试时提示:“无法打开该页面,不支持打开 https://xxxxxx,请在“小程序右上角更多->反馈与投诉”中和开发者反馈。” 解决方法:需要配…...
海外媒体发稿:媒体宣发套餐的作用分享-华媒舍
一、神奇媒体宣发套餐 神奇媒体宣发套餐是一项专业的多媒体宣传推广服务,旨在帮助企业、个人快速提升品牌知名度和曝光度。它通过全面覆盖主流媒体、社交网络以及各大网络平台,将您的宣传信息传递给广泛的受众群体,实现全方位、多角度的宣传…...
【R语言】plot输出窗口大小的控制
如果需要输出png格式的图片并设置dpi,可采用以下代码 png("A1.png",width 10.09, height 10.35, units "in",res 300) 为了匹配对应的窗口大小,在输出的时候保持宽度和高度一致即可,步骤如下: 如上的“10…...
【shell脚本实战案例】数据磁盘初始化
文章目录 一、案例应用场景二、案例需求三、案例算法四、代码实现五、实现验证 🌈你好呀!我是 山顶风景独好 🎈欢迎踏入我的博客世界,能与您在此邂逅,真是缘分使然!😊 🌸愿您在此停留…...
1.7 计算机体系结构分类
Flynn分类法 CISC与RISC...
数据结构之B树:深入了解与应用
目录 1. B树的基本概念 1.1 B树的定义 1.2 B树的性质 1.3 B树的阶 2. B树的结构 2.1 节点结构 2.2 节点分裂 2.3 节点合并 3. B树的基本操作 3.1 搜索 3.2 插入 3.3 删除 4. B树的应用 4.1 数据库索引 4.2 文件系统 4.3 内存管理 5. B树的优势和局限 5.1 优势…...
Tensorflow入门实战 T06-Vgg16 明星识别
目录 1、前言 2、 完整代码 3、运行过程结果 4、遇到的问题 5、小结 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 1、前言 这周主要是使用VGG16模型,完成明星照片识别。 2、 完整代…...
SpringBoot 3.3.1 + Minio 实现极速上传和预览模式
统一版本管理 <properties><minio.version>8.5.10</minio.version><aws.version>1.12.737</aws.version><hutool.version>5.8.28</hutool.version> </properties><!--minio --> <dependency><groupId>io.m…...
Linux: network: 丢包分析的另一个途径 tracing
丢包的另一个思路,内核里有些counter的计数,记录的不准确。这个时候怎么办?就需要使用另外一个方式:/sys/kernel/debug/tracing/event/skb/kfree_skb 的跟踪功能。这个算是对counter的一个补充,可以拿来做统计分析使用…...
【保姆级教程+配置源码】在VScode配置C/C++环境
目录 一、下载VScode 1. 在官网直接下载安装即可 2. 安装中文插件 二、下载C语言编译器MinGW-W64 三、配置编译器环境变量 1. 解压下载的压缩包,复制该文件夹下bin目录所在地址 2. 在电脑搜索环境变量并打开 3. 点击环境变量→选择系统变量里的Path→点击编…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
