常用设计模式之单例模式

news2024/11/24 10:31:55

文章目录

  • 饿汉式和懒汉式
  • 多线程中的懒汉式
  • 单例模式内存释放问题
  • 单例模式优缺点
  • 单例应用场景
  • 测试代码

饿汉式和懒汉式

单例模式是指在任何时候都保证只有一个类实例,并提供一个访问它的全局访问节点。

单例模式结构图:
在这里插入图片描述
解释:单例模式就是一个类,但这个类有点特殊,特殊在他只能创建一个实例,而对外就是提供一个外界可以访问的实例化方法。

但是如何保证让它只能实例化一个对象?示例代码如下:

// 饿汉式写法
class Singleton {
private:
    Singleton() {}
private:
    static Singleton* sig;
public:
    static Singleton* instance() {
        return sig;
    }
    // 删除带掉拷贝构造和赋值拷贝构造
    Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;
};
Singleton* Singleton::sig = new Singleton;

这里声明了一个Single的单例类,类中有两个与其它类不同的地方,一个就是它的构造函数是私有的,这样做的目的就是防止外界调用构造函数,而只要外界不能调用构造函数那么就不能对该类进行实例化(类内可以访问私有的构造函数所以只能类内实例化)。所以提供一个instance专门用来实例化的函数,用来对一个没有实例化的对象进行实例化,外界只能通过该函数来获取实例。sig和instance声明为static的原因是静态成员函数只能调用静态成员。

到这里可以说是已经实现了一个基本的单例类。而这只是单例类的一种懒汉式写法。

懒汉式写法有如下优缺点:

优点:饿汉式单例是最简单的一种单例形式,它没有添加任何的锁,执行效率最高,并且能够保证线程安全。

缺点:某些情况下,造成内存浪费,因为对象未被使用的情况下就会被初始化,如果一个项目中的类多达上千个,在项目启动的时候便开始初始化可能并不是我们想要的。

下面来介绍另一种饿汉式写法。

多线程中的懒汉式

在多线程中上面的懒汉式明显是存在问题的,比如当两个线程同时执行到if (sig == nullptr)语句且条件为true时,然后两个线程都会去执行sig = new Single;这一句代码,这就违反了单例只能实例化一个对象的规定。所以下面是对懒汉式改进后的结果:

// 懒汉式写法
class Singleton {
private:
    Singleton() {}
private:
    static mutex lock;
    static Singleton* sig;
public:
    static Singleton* instance() {
        if (sig == nullptr) {
            lock_guard<mutex> lk(lock);
            if (sig == nullptr)
                sig = new Singleton();
        }
        return sig;
    }
    Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;
};
Singleton* Singleton::sig = nullptr;
mutex Singleton::lock; // 内外定义,链接时分配内存

lock_guard<mutex> qlock(lock)是确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其它线程试图进入锁定的代码,则它将一直处于等待状态,直到该对象被释放为止。而外面再加一层是否为空的判断是为了保证执行lock_guard<mutex> qlock(lock)的时候确保当前的对象时没有被实例过的,因为上锁操作对性能是有影响的,所以这里会有一个双重的判定。

单例模式内存释放问题

对于单例模式我们开辟的内存其实不用释放,原因是单例对象在内存中只保存了一份所以对空间占用不是很高,还有单例对象实例的对象我们一般都会经常用到所以最好还是不要释放,但是如果你确实需要对实例的对象进行释放的话我们可以在类中再增加一个类,该类就类似于智能指针的作用,专门用来负责单例对象的释放。

单例模式优缺点

优点:
在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
避免对资源的多重占用(比如写文件操作)。

缺点:
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

单例应用场景

Windows系统的任务管理器。
Windows系统的回收站。
操作系统的文件系统,一个操作系统只能有一个文件系统。
数据库连接池的设计与实现。
多线程的线程池设计与实现。

测试代码

#include <iostream>
#include <mutex>
using namespace std;

#define LAZY
#ifdef LAZY

// 懒汉式写法
class Singleton {
private:
    Singleton() {}
private:
    static mutex lock;
    static Singleton* sig;
public:
    static Singleton* instance() {
        if (sig == nullptr) {
            lock_guard<mutex> lk(lock);
            if (sig == nullptr)
                sig = new Singleton();
        }
        return sig;
    }
    Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;
};
Singleton* Singleton::sig = nullptr;
mutex Singleton::lock; // 内外定义,链接时分配内存

#elif HUNGRY

// 饿汉式写法
class Singleton {
private:
    Singleton() {}
private:
    static Singleton* sig;
public:
    static Singleton* instance() {
        return sig;
    }
    Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;
};
Singleton* Singleton::sig = new Singleton;

#endif

int main()
{
    Singleton * sig = nullptr;
    sig = Singleton::instance();
    if (sig) {
        cout << "instance success" << endl;
    } else {
        cout << "instance failed" << endl;
    }
    return 0;
}

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

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

相关文章

罗湖区田心村旧改确认实施主体的公示,华润集团开发

深圳市罗湖区城市更新和土地整备局发布关于罗湖区笋岗街道田心村改造项目一期子项目2&#xff08;1-14、1-16、1-17地块&#xff09;确认实施主体的公示。 田心村改造项目位于罗湖区笋岗街道田心村&#xff0c;2012年4月&#xff0c;深圳市城市规划委员会建筑与环境艺术委员会2…

关于ElementPlus中的表单验证

关于ElementPlus中表单的校验规则&#xff0c;官网文档已经给出了&#xff0c;但是没有说明性文字&#xff0c;所以我想来记录一下&#xff0c;给出一些文字说明 ElementPlus中的简单校验 ElementPlus的表单的一般结构是&#xff1a; <el-form><el-form-item>&l…

(一)CSharp-Net框架

.NET框架由三部分组成&#xff1a; 1.编程工具。 2.基类库(BCL). 3.公共语言运行库(CLR) CLR 在运行时管理程序的执行&#xff0c;包括以下内容&#xff1a; 内存管理和垃圾收集。代码安全验证。代码执行、线程管理及异常处理。 NET 框架的特点以及其带来的好处&#xff1a…

web测试工程师的工作职责(合集)

web测试工程师的工作职责1 职责: 1、 负责数据平台产品的测试工作&#xff0c;参与产品需求分析&#xff0c;负责方案制定,并能预先评估项目风险&#xff0c;确保测试活动的顺利开展; 2、 深入理解系统内部的设计原理&#xff0c;并能从测试的角度提供优化意见; 3、 根据产品需…

【Linux】多线程概念初讲

线程大章节第一篇文章 文章目录 前言一、linux线程基本概念二、线程与进程的对比 1.线程控制的接口总结 前言 什么是线程呢&#xff1f; 在一个程序里的一个执行路线就叫做线程&#xff08; thread &#xff09;。更准确的定义是&#xff1a;线程是 “ 一个进程内部的控制…

Nginx+Tomcat负载均衡、动静分离,4层代理,7层代理

一&#xff1a;7层反向代理 Nginx 服务器&#xff1a;192.168.52.200:80 Tomcat服务器1&#xff1a;192.168.52.201:80 Tomcat服务器2&#xff1a;192.168.52.108:8080 192.168.52.108:8081 一.部署Nginx 负载均衡器 1.关闭防火墙 注意&#xff1a;所有的虚拟机都要注意关闭防…

硬件入门什么是之电阻

第1章 硬件入门什么是之电阻 文章目录 第1章 硬件入门什么是之电阻[TOC] 一、电阻基本概念二、电路设计实际应用1.限流( 恒流)2.分压 { 采样&#xff1a;电阻精度至少为1%}3.上拉和下拉4.分担功耗5.通信芯片的阻抗匹配 总结 一、电阻基本概念 对电流有阻碍作用的导体叫做&…

NFS(Network File System)服务搭建

NFS基础服务搭建 环境介绍:服务拓扑:nfs serverclient1临时挂载永久挂载client2临时挂载永久挂载注意事项:环境介绍: 系统全为centos7系统 使用本地yum源 服务拓扑: nfs server yum -ty install nfs-utilst rpcbind setenforce 0 mkdir /var/{world,cloud} echo -e “/va…

【Python XML】零基础也能轻松掌握的学习路线与参考资料

Python是一种广泛使用的编程语言&#xff0c;可以用来处理各种数据类型&#xff0c;并且具有广泛的应用&#xff0c;从Web开发到人工智能都能够胜任。在这样的大环境下&#xff0c;XML&#xff08;扩展标记语言&#xff09;成为了一项非常重要的数据交换格式&#xff0c;它提供…

JAVA对象头的指针压缩

JAVA对象头的指针压缩 文章目录 JAVA对象头的指针压缩对象在JVM中的内存布局对象的访问定位压缩实验实验步骤压缩策略组合压缩内容压缩后的影响指针压缩的实现 JVM内存关键大小 对象在JVM中的内存布局 在 Hotspot 虚拟机中,对象的内存布局主要由 3 部分组成&#xff1a; 对象头…

OpenMMLab AI 实战营笔记4——MMPreTrain算法库:构建高效、灵活、可扩展的深度学习模型

文章目录 摘要一、工具箱介绍二、丰富的模型三、推理API四、环境搭建——OpenMMLab软件栈五、OpenMMLab重要概念——配置文件六、代码框架七、配置及运作方式经典主干网络残差网络Vison Transformer(VIT)注意力机制自监督学习常见类型SimCLRMAE自监督学习 多模态CLIPBLIPOthers…

jvm 命令和工具

目录 堆内存分析工具 MAT ZProfiler - 线上的mat EagleEye-MProf - 命令行 命令行 线程池排查 jstack jmap -dump jmap -heap jstat 堆内存分析工具 MAT eclipse官方推出的本地内存分析工具&#xff0c;运行需要大量内存&#xff0c;从使用角度来讲&#xff0c;并不…

Mysql查询优化

Mysql查询优化器 在多种情况下,可能会导致查询结果从缓存中清除,例如:. 数据可能已被修改 您可能运行了一条语句,其文本与缓存的语句略有不同(小写/大写,换行符,...) 缓存可能已达到其大小限制之一(内存,查询计数,块等),并决定逐出您的特定查询 高速缓存碎片过多…

DatenLord前沿技术分享 No.26

达坦科技专注于打造新一代开源跨云存储平台DatenLord&#xff0c;通过软硬件深度融合的方式打通云云壁垒&#xff0c;致力于解决多云架构、多数据中心场景下异构存储、数据统一管理需求等问题&#xff0c;以满足不同行业客户对海量数据跨云、跨数据中心高性能访问的需求。达坦科…

SpringBoot+MyBatisplus搭建校园新闻平台——已开源

概述 开发背景 校园新闻平台是以新闻宣传机构的在线信息发布需求为基础&#xff0c;随着数字化和信息化的快速发展&#xff0c;校园新闻在校园内的传播和沟通中变得越来越重要。学校需要一个有效的管理系统来整合、发布和传播校园新闻&#xff0c;以满足师生、校友和其他利益…

我对测试行业发展和自我价值诉求的思考

测试圈子生态的思考 其实测试的生态&#xff0c;说起来蛮简单的&#xff0c;一个词语概括就是两极分化。有个梗&#xff1a;hand hands&#xff0c;load loads&#xff0c;太贴切了。 两极分化这个词&#xff0c;可以从下面三个维度来看&#xff1a; 薪资 我认识的测试也算不少…

搜索插入位置 力扣 Python

题目描述&#xff1a; 解题代码&#xff1a; class Solution:def searchInsert(self, nums: List[int], target: int) -> int:if target in nums:return nums.index(target)else:nums.append(target)nums.sort()return nums.index(target)题目分析&#xff1a; 时间复杂度…

0804空间直线及其方程-向量代数与空间解析几何

文章目录 1 空间直线方程1.1 空间直线的一般方程1.2 空间直线的对称式方程1.3 空间直线的参数方程1.4 空间直线的两点式方程 3 两直线的夹角4 直线与平面的夹角4.1 定义4.2 夹角的正弦公式 5 例题6 平面束方程结语 1 空间直线方程 1.1 空间直线的一般方程 空间直线L可以看做是…

【3DsMAX】从零开始建房(4)

目录 1. 制作二层主体 2. 制作二楼顶层栏杆 1. 制作二层主体 将二层的长方体转换为可编辑多边形&#xff0c;将左半部分的点向左移动一点距离 选中左右边线进行连接 移动连接线 选中如下的面挤出 选中一条边线&#xff0c;再点击环形 再点击连接 挤出 选中如下一条边线向上移…

【Windows安装】Windows详细安装nginx部署教程

1、先下载直接去官网nginx.org 点击后就会下载&#xff0c;下载完成后开始安装&#xff0c;其实官网已经告诉了如何安装&#xff0c;右侧“documentation -> nginx windows”就有详细的说明&#xff0c;只是英文而已 2、下载完成后&#xff0c;解压缩&#xff0c;运行cmd&a…