单例模式的介绍
单例模式(Singleton)是一种创建型设计模式,它确保一个类只有一个实例,并提供全局访问点。其核心思想是通过限制类的实例化次数,防止多个实例同时存在,从而避免了多线程竞争和资源浪费,提高了代码的可维护性和可扩展性。
单例模式通常适用于以下场景:
- 系统中某个类只能存在一个实例,例如系统配置、日志管理器等。
- 需要频繁访问同一个对象或资源,但又不希望每次都去创建新的对象。
- 为了确保数据的一致性和完整性,需要限制全局变量的访问权限。
实现单例模式的方法有很多种,常见的包括懒汉式、饿汉式、双重检查锁等。具体实现方式可以根据实际情况选择,但需要注意线程安全性、效率等问题。
在 C++ 中,可以使用静态成员变量或者静态局部变量来实现单例模式。静态成员变量在程序启动时就会被初始化,因此是线程安全的,但需要手动释放资源。静态局部变量则是在首次调用时初始化,虽然不需要手动释放资源,但需要考虑线程安全性和可重入性等问题。
总之,单例模式是一种简单而又实用的设计模式,可以在很多场景下提高代码的可维护性和可扩展性。在使用单例模式时,需要根据具体情况选择适合的实现方式,并考虑线程安全性、效率等问题。
在单线程中,这两种方式都可以使用。然而,在多线程环境下,懒汉式单例模式可能会引发线程安全问题,因为多个线程可能同时访问并创建该单例对象。为了解决这个问题,可以使用以下两种方式:
加锁:在getInstance函数中使用互斥锁来保证线程安全。
双检查锁:在getInstance函数中使用双检查锁机制,先检查instance是否为空,如果为空,则获取互斥锁,再次检查instance是否为空,如果为空,则创建对象。
综上所述,饥汉式单例模式更适合在线程中使用,因为它没有线程安全问题,并且更高效,因为它在程序启动时就已经创建了实例。但是需要注意的是,饥汉式单例模式可能会增加程序启动时间和内存使用。如果单例对象非常庞大,或者不一定在每次都被使用时都需要创建,那么懒汉式单例模式可能更适合使用。
#include <iostream> #include <thread> #include <mutex>class Singleton { private:static Singleton* instance;static std::mutex mutex;Singleton() {} public:static Singleton* getInstance() {std::lock_guard<std::mutex> lock(mutex);if (instance == nullptr) {instance = new Singleton();}return instance;}void showMessage() {std::cout << "Hello from Singleton!" << std::endl;} };Singleton* Singleton::instance = nullptr; std::mutex Singleton::mutex;void threadFunction() {Singleton* singleton = Singleton::getInstance();singleton->showMessage(); }int main() {const int numThreads = 5;std::thread threads[numThreads];for (int i = 0; i < numThreads; ++i) {threads[i] = std::thread(threadFunction);}for (int i = 0; i < numThreads; ++i) {threads[i].join();}return 0; }
当在多线程环境中使用单例模式时,需要考虑线程安全性以避免多个线程同时创建实例或访问共享资源的问题。以下是一个示例,在多线程环境下使用懒汉式单例模式,并通过加锁确保线程安全:。。。。
在上面的示例中,我们使用了
std::mutex
来确保在getInstance()
函数中对单例对象进行加锁操作,从而保证多线程环境下的线程安全性。每个线程调用getInstance()
函数来获取单例实例,并调用showMessage()
方法输出信息。这样,在多线程环境下,每个线程都会获得同一个实例,并且不会出现多个实例被创建的情况。通过加锁操作,确保了线程安全性。
#include <iostream>class Singleton {
public:static Singleton& getInstance() {static Singleton instance; // 在首次调用时初始化静态局部变量return instance;}void showMessage() {std::cout << "Hello, I am a singleton instance!" << std::endl;}private:Singleton() {} // 将构造函数私有化,防止外部实例化对象Singleton(const Singleton&) = delete; // 禁用拷贝构造函数Singleton& operator=(const Singleton&) = delete; // 禁用赋值运算符
};int main() {Singleton& singleton = Singleton::getInstance();singleton.showMessage();// 以下代码会报错,因为构造函数是私有的// Singleton newSingleton;// Singleton anotherSingleton = singleton;return 0;
}
class Singleton {
private:static Singleton* instance;Singleton(){}
public:static Singleton* getInstance(){if(instance == nullptr){instance = new Singleton();}return instance;}
};Singleton* Singleton::instance = nullptr;
相关文章:
单例模式的介绍
单例模式(Singleton)是一种创建型设计模式,它确保一个类只有一个实例,并提供全局访问点。其核心思想是通过限制类的实例化次数,防止多个实例同时存在,从而避免了多线程竞争和资源浪费,提高了代码…...

JavaSec 基础之 XXE
文章目录 XMLReaderSAXReaderSAXBuilderDocumentBuilderUnmarshaller**SAXParserFactory**XMLReaderFactoryDigester总结 XMLReader public String XMLReader(RequestBody String content) {try {XMLReader xmlReader XMLReaderFactory.createXMLReader();// 修复:…...

AI:137-基于深度学习的实时交通违法行为检测与记录
🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带关键代码,详细讲解供大家学习,希望…...

【深度学习笔记】3_14 正向传播、反向传播和计算图
3.14 正向传播、反向传播和计算图 前面几节里我们使用了小批量随机梯度下降的优化算法来训练模型。在实现中,我们只提供了模型的正向传播(forward propagation)的计算,即对输入计算模型输出,然后通过autograd模块来调…...

Jenkins详解
目录 一、Jenkins CI/CD 1、 Jenkins CI/CD 流程图 2、介绍 Jenkins 1、Jenkins概念 2、Jenkins目的 3、特性 4、产品发布流程 3、安装Jenkins 1、安装JDK 2、安装tomcat 3.安装maven 4安装jenkins 5.启动tomcat,并页面访问 5.添加节点 一、Jenkins CI/…...

Java8 Stream API 详解:流式编程进行数据处理
🏷️个人主页:牵着猫散步的鼠鼠 🏷️系列专栏:Java全栈-专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默&…...

【机器学习】特征选择之过滤式特征选择法
🎈个人主页:豌豆射手^ 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:机器学习 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进…...

C#_扩展方法
简述: 扩展方法所属类必需是静态类(类名依据规范通常为XXXExtension,XXX为被扩展类)扩展方法必需是公有的静态方法扩展方法的首个参数由this修饰,参数类型为被扩展类型 示例: static class DoubleExtens…...

LeetCode 热题 100 | 二叉树(一)
目录 1 基础知识 1.1 先序遍历 1.2 中序遍历 1.3 后序遍历 2 94. 二叉树的中序遍历 3 104. 二叉树的最大深度 4 226. 翻转二叉树 5 101. 对称二叉树 菜鸟做题,语言是 C 1 基础知识 二叉树常见的遍历方式有: 先序遍历中序遍历后序遍历…...
k8s之nodelocaldns与CoreDNS组件
在 Kubernetes 集群中,通常是先通过 NodeLocal DNS Cache 进行域名解析,如果 NodeLocal DNS Cache 没有找到对应的域名解析结果,才会向 CoreDNS 发起请求。在部署层面上看nodelocaldns会在每个节点上运行一个 DNS 缓存服务,而Core…...

Java中的访问修饰符
Java中的访问修饰符 java 提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限: 公开级别:用 public 修饰,对外公开受保护级别:用 protected 修饰,对子类和同一个包中的类公开默认级别:没有修饰符号,向同一个包的类公开私有级别:用 private 修饰,只…...

【论文解读】transformer小目标检测综述
目录 一、简要介绍 二、研究背景 三、用于小目标检测的transformer 3.1 Object Representation 3.2 Fast Attention for High-Resolution or Multi-Scale Feature Maps 3.3 Fully Transformer-Based Detectors 3.4 Architecture and Block Modifications 3.6 Improved …...

springboot215基于springboot技术的美食烹饪互动平台的设计与实现
美食烹饪互动平台的设计与实现 摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统美食信息管理难度大&…...

Rust核心:【所有权】相关知识点
rust在内存资源管理上采用了(先进优秀?算吗)但特立独行的设计思路:所有权。这是rust的核心,贯穿在整个rust语言的方方面面,并以此为基点来重新思考和重构软件开发体系。 涉及到的概念点:借用&am…...

单片机05__串口USART通信__按键控制向上位机传输字符串
串口USART通信 通用UART介绍 1.通信的概念 计算机与外界进行信息交换的过程称之为通信。 在通信的过程中,通信双方都需要遵守的规则称之为通信协议。 硬件协议:将数据以什么样的方式传输过去 软件协议:将数据以什么样的顺序传输过去 2.常用…...

实习日志30
概要 高拍仪硬件通信原理,WebSocket源码解析(JavaScript) WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。 WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据…...

【MySQL】探索表结构、数据类型和基本操作
表、记录、字段 数据库的E-R(entity-relationship,实体-关系)模型中有三个主要概念: 实体集 、 属性 、 关系集 。 一个实体集对应于数据库中的一个表,一个实体则对应于数据库表 中的一行,也称为一条记录。…...
解决采集时使用selenium被屏蔽的办法
解决采集时使用selenium被屏蔽的办法 实用seleniumbase uc模式 from seleniumbase import Driver driver Driver(ucTrue) # 使用UC模式UC模式是基于undetected-chromedriver 但做了一些优化更新,使用起来更方便 官方例子: from seleniumbase import …...

stream流-> 判定 + 过滤 + 收集
List<HotArticleVo> hotArticleVos hotArticleVoList .stream() .filter(x -> x.getChannelId().equals(wmChannel.getId())).collect(Collectors.toList()); 使用Java 8中的Stream API对一个名为hotArticleVoList的列表进行过滤操作,筛选出符合指定条件…...

人工智能在测绘行业的应用与挑战
目录 一、背景 二、AI在测绘行业的应用方向 1. 自动化特征提取 2. 数据处理与分析 3. 无人机测绘 4. 智能导航与路径规划 5. 三维建模与可视化 6. 地理信息系统(GIS)智能化 三、发展前景 1. 技术融合 2. 精准测绘 3. 智慧城市建设 4. 可…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践,很多人以为AI已经强大到不需要程序员了,其实不是,AI更加需要程序员,普通人…...