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

C# 设计模式之单例模式

总目录


前言

本文是个人基于C#学习设计模式总结的学习笔记,希望对你有用!


1 基本介绍

定义:确保一个类只有一个实例,并提供一个全局访问点。

本质就是保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个。

2 适用场景

单例模式通常适用于在整个应用程序中只需要一个实例化对象的场景,以确保资源的高效利用和应用程序的稳定性。

  • 日志系统:在应用程序中,通常只需要一个日志系统,以避免在多个地方创建多个日志对象。这一般是由于共享的日志文件一直处于打开状态,所以只能有一个实例去操作,否则内容不好追加也有可能造成资源占用加剧资源消耗。
  • 数据库连接池:在应用程序中,数据库连接池是一个非常重要的资源,单例模式可以确保在应用程序中只有一个数据库连接池实例,避免资源浪费。主要是节省打开或者关闭数据库连接所引起的效率损耗,因为何用单例模式来维护,就可以大大降低这种损耗。
  • 配置文件管理器:在应用程序中,通常只需要一个配置文件管理器来管理应用程序的配置文件,单例模式可以确保在整个应用程序中只有一个配置文件管理器实例。这个是由于配置文件是共享的资源。
  • 缓存系统:在应用程序中,缓存系统是一个重要的组件,单例模式可以确保在整个应用程序中只有一个缓存实例,以提高应用程序的性能。
  • 网站在线人数统计:其实就是全局计数器,也就是说所有用户在相同的时刻获取到的在线人数数量都是一致的。
  • GUI组件:在图形用户界面(GUI)开发中,单例模式可以确保在整个应用程序中只有一个GUI组件实例,以确保用户界面的一致性和稳定性。

3 实现方式

  • 懒汉式:类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建。
  • 饿汉式:类加载就会导致该单实例对象被创建。
  • 懒汉式,公有静态方法,非线程安全
    /// <summary>/// 单例模式的实现/// </summary>public class Singleton{//定义一个静态变量用于保存实例private static Singleton instance;private Singleton(){//将构造函数私有化,使外界不能创建该类实例}//定义公有静态方法,提供一个全局访问点(也可以定义公有属性作为全局访问点)public static Singleton GetInstance(){if (instance == null){instance = new Singleton();}return instance;}}

在GetInstance方法中,我们检查instance是否为null,如果是,则创建一个新的Singleton实例并将其赋值给instance。最后,我们返回instance实例。这样,无论何时调用Instance属性,它都将返回同一个Singleton实例。通过这种方式,我们实现了单例模式,确保了整个应用程序中只有一个Singleton实例存在,并提供了一个全局访问点来访问该实例。

  • 懒汉式,公有属性,非线程安全
    /// <summary>/// 单例模式的实现/// </summary>public class Singleton{//定义一个静态变量用于保存实例private static Singleton _instance;//定义公有静态属性,提供一个全局访问点public static Singleton Instance{get {if (_instance == null){_instance = new Singleton();}return _instance;}set { _instance = value; }}private Singleton(){//将构造函数私有化,使外界不能创建该类实例}}

此种方法同上面的方法是一样的作用,只不过调用的时候,一个是使用方法,一个是使用属性而已。

  • 懒汉式,公有属性,线程安全

以上的代码实现了在单线程下是OK的,然而在多线程的情况下会得到多个Singleton 实例,因为在两个线程同时运行GetInstance方法时,此时两个线程判断(_instance ==null)这个条件时都返回真,此时两个线程就都会创建Singleton的实例,这样就违背了我们单例模式初衷了,既然上面的实现会运行多个线程执行,那我们对于多线程的解决方案自然就是使GetInstance方法在同一时间只运行一个线程运行就好了

    /// <summary>/// 单例模式的实现/// </summary>public class Singleton{//定义一个静态变量用于保存实例private static Singleton _instance;//定义一个线程锁private static readonly object _instanceLock = new object();//定义公有静态属性,提供一个全局访问点public static Singleton Instance{get {lock (_instanceLock){if (_instance == null){_instance = new Singleton();}}return _instance;}set { _instance = value; }}private Singleton(){//将构造函数私有化,使外界不能创建该类实例}}
  • 懒汉式,公有属性,双重锁定,线程安全

上面这种解决方案确实可以解决多线程的问题,但是上面代码对于每个线程都会对线程辅助对象locker加锁之后再判断实例是否存在,对于这个操作完全没有必要的,因为当第一个线程创建了该类的实例之后,后面的线程此时只需要直接判断(_instance==null)为假,此时完全没必要对线程辅助对象加锁之后再去判断,所以上面的实现方式增加了额外的开销,损失了性能,为了改进上面实现方式的缺陷,我们只需要在lock语句前面加一句(_instance==null)的判断就可以避免锁所增加的额外开销,这种实现方式我们就叫它 “双重锁定”

    /// <summary>/// 单例模式的实现/// </summary>public class Singleton{//定义一个静态变量用于保存实例private static Singleton _instance;//定义一个线程锁private static readonly object _instanceLock = new object();//定义公有静态属性,提供一个全局访问点public static Singleton Instance{get {if (_instance==null){lock (_instanceLock){if (_instance == null){_instance = new Singleton();}}}return _instance;}set { _instance = value; }}private Singleton(){//将构造函数私有化,使外界不能创建该类实例}}
  • 饿汉式
    /// <summary>/// 单例模式的实现/// </summary>public class Singleton{//定义一个私有静态的只读的全局变量private static readonly Singleton instance = new Singleton();private Singleton(){//将构造函数私有化,使外界不能创建该类实例}//设置为静态方法则可在外边无需创建该类的实例就可调用该方法public static Singleton GetInstance(){return instance;}}

在c#中使用静态初始化时无需显示地编写线程安全代码,C# 与 CLR 会自动解决前面提到的懒汉式单例类时出现的多线程同步问题。

当整个类被加载的时候,就会自行初始化 instance 这个静态只读变量。

而非在第一次调用 GetInstance()时再来实例化单例类的唯一实例,所以这就是一种饿汉式的单例类


总结

以上就是今天要讲的内容,本文介绍了单例模式的使用,而希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。


参考资料
C#设计模式(1)——单例模式
C#中单例模式详解

相关文章:

C# 设计模式之单例模式

总目录 前言 本文是个人基于C#学习设计模式总结的学习笔记&#xff0c;希望对你有用&#xff01; 1 基本介绍 定义&#xff1a;确保一个类只有一个实例&#xff0c;并提供一个全局访问点。 本质就是保证在整个应用程序的生命周期中&#xff0c;任何一个时刻&#xff0c;单例…...

【组合数学】【Python】【小练习】一、斯特灵近似式求阶乘

一、问题介绍 斯特灵&#xff08;Stirling&#xff09;近似式&#xff0c;是数学分析中&#xff0c;用于求阶乘近似值的一个常用公式&#xff0c;其简单的表述形式为&#xff1a; 二、Python实现 使用Python&#xff0c;循环从n1至n98&#xff0c;分别输出n的阶乘值、斯特灵公…...

【IEEE Fellow特邀报告,JPCS独立出版】第四届电子通信与计算机科学技术国际学术会议(ECCST 2024,9月20-22)

2024年第四届电子通信与计算机科学技术国际学术会议将于2024年9月20-22日在中国上海举行。 会议旨在为从电子与通信、网络、人工智能与计算机技术研究的专家学者、工程技术人员、技术研发人员提供一个共享科研成果和前沿技术&#xff0c;了解学术发展趋势&#xff0c;拓宽研究思…...

DockerCompose部署示例

目录 前言 1. 初识DockerCompose 2. 安装DockerCompose 3. 部署微服务项目 1&#xff09;找一个目录&#xff0c;创建一个新的cloud-demo文件夹。 2&#xff09;在cloud-demo文件夹创建一个docker-compose.yml文件&#xff0c;然后编写下面内容&#xff1a; 3&#xff09…...

【云原生】Helm来管理Kubernetes集群的详细使用方法与综合应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

电源插头应该统一方向

大家在使用插排的时候就会发现&#xff0c;有的横向&#xff0c;有的竖向。 国家强制规定&#xff0c;统一方向&#xff0c;插排能方便使用。...

大学新生编程入门最佳攻略

引言 编程的重要性&#xff1a;简述编程在当今社会的地位&#xff0c;为何它是大学生的必备技能。目标设定&#xff1a;明确文章旨在帮助新生从零基础开始&#xff0c;逐步成长为编程高手。 方向一&#xff1a;编程语言选择 1. 编程语言概览 介绍几种流行语言&#xff1a;如…...

MySQL 的binlog 、undolog 、redolog

Binlog (二进制日志) bin Log 作用 用于记录所有修改数据库数据的 SQL 语句或行级别的变化&#xff0c;主要用于主从复制和数据恢复。 binlog格式 STATEMENT模式&#xff1a;binlog里面记录的就是SQL语句的原文。优点是并不需要记录每一行的数据变化&#xff0c;减少了binlo…...

【计算机网络】三次握手、四次挥手

问&#xff1a;三次握手 四次挥手 TCP 连接过程是 3 次握手&#xff0c;终止过程是 4 次挥手 3次握手 第一步&#xff1a;客户端向服务器发送一个带有 SYN&#xff08;同步&#xff09;标志的包&#xff0c;指示客户端要建立连接。 第二步&#xff1a;服务器收到客户端的请求…...

Spring Boot中的全局异常处理:@RestControllerAdvice的应用

在现代Web开发中&#xff0c;异常处理是一个不可或缺的部分。良好的异常处理不仅能提高系统的健壮性&#xff0c;还能提升用户体验。在Spring Boot中&#xff0c;全局异常处理的实现可以通过使用RestControllerAdvice注解来完成。本文将详细介绍如何使用RestControllerAdvice和…...

指令数据的构建

文章目录 基于现有的 NLP 任务数据集构建基于日常对话数据构建基于合成数据构建指令微调(Instruction Tuning)是指使用自然语言形式的数据对预训练后的大语言模型进行参数微调,这一术语由谷歌研究员在 2022 年的一篇 ICLR 论文中正式提出。在另外一些参考文献中,指令微调也…...

论文解读(14)-GeoCLIP

加油&#xff0c;加油&#xff01; 原文&#xff1a; GeoCLIP: Clip-Inspired Alignment between Locations and Images for Effective Worldwide Geo-localization &#xff08;2309.16020 (arxiv.org)&#xff09; 这一篇的重点在于范围放宽到全球了 摘要 首先指出了目前…...

MySQL基础练习题16-电影评分

题目 准备数据 分析数据 总结 题目 查找评论电影数量最多的用户名。如果出现平局&#xff0c;返回字典序较小的用户名。 查找在 February 2020 平均评分最高 的电影名称。如果出现平局&#xff0c;返回字典序较小的电影名称。 准备数据 ## 创建库 create database db; u…...

CRMEB-众邦科技 使用笔记

1.启动项目报错 Unable to load authentication plugin ‘caching_sha2_password’. 参考&#xff1a;http://t.csdnimg.cn/5EqaE 解决办法&#xff1a;升级mysql驱动 <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</ar…...

npm与webpack的学习笔记

npm 定义&#xff1a;npm是Node.js标准的软件包管理器。它起初是作为下载和管理Node.js包依赖的方式&#xff0c;但其现在也已成为前端JavaScript中使用的工具。 包 包&#xff1a;将模块、代码、其他资料聚合成一个文件夹 包的分类&#xff1a; 项目包&#xff1a;主要用…...

Vue 生命周期选项:2.x 与 3.x 的全面解析及案例分享二

目录 Vue3.X生命周期 介绍 流程图 案例 ​​​​​​​this.$nextTick Vue 生命周期选项:2.x 与 3.x 的全面解析及案例分享一-CSDN博客 Vue3.X生命周期 介绍 beforeCreate:在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。此时无法访…...

Linux centos7 安装sftp

这里写自定义目录标题 指定 SSH 默认端口 (通常是22)添加自定义端口确保 SFTP 子系统配置存在匹配自定义端口的配置 在 CentOS 7 上安装 SFTP 并使用自定义端口 22345 启动&#xff0c;同时不影响现有的 SSH 登录&#xff0c;可以按照以下步骤进行配置&#xff1a; 步骤 1: 安…...

Java未来还是霸主吗?Java 在当今企业中的未来到底是什么?

Java 及其生态系统对于许多现代企业的成功至关重要。它是一种多功能语言&#xff0c;对许多用例提供强大支持&#xff0c;并具有强大的新功能来应对棘手的情况。但您可能会问自己&#xff1a;Java 的未来是什么&#xff1f; 尽管自 1999 年以来 Java 一直是软件开发领域的关键角…...

【C++】类和对象——Lesson2

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C &#x1f680;本系列文章为个人学习笔记…...

常用传感器讲解十五--触摸传感器(KY-036)

常用传感器讲解十五–触摸传感器&#xff08;KY-036&#xff09; 具体讲解 这个比较简单&#xff0c;就是触摸后给个信号 电路连接 在Arduino上将VCC引脚连接到5V。 将GND连接到Arduino的GND。 将OUT连接到Arduino上的D2 代码实现 void setup() {pinMode(2, INPUT);Seri…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...