C# 创建型设计模式之----单例模式

设计模式相信很多人在大学都有学过,当时学的时候肯定都学懂了的但在后来的程序开发中却很少会用到,好像其实际意义并不大。下面对其的简单说明希望能对大家的实际开发有所帮助和理解,当然这也仅是我的个人见解。用做自己的备忘录功能。

1、单例模式基本介绍

单例模式是一种确保一个类只有一个实例的设计模式

适用于需要频繁实例化然后销毁的对象,创建对象消耗资源过多,但又经常用到的对象。或者全局有且仅能有一个实例化的对象。其本质就是保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个

  • 特性和功能:确保一个类只有一个实例,并提供一个全局访问点。
  • 使用环境:当类只需要一个实例,且易于访问,且实例应在整个应用程序中共享时。
  • 注意事项:需要注意线程安全问题。
  • 优点:可以确保一个类只有一个实例,减少了内存开销。
  • 缺点:没有接口,扩展困难。

2、适用场景(部分)

2.1、 要求生成唯一序列号的环境;

比如记录网站实时登录人数,或者消息报文的编号。

2.2、在整个项目中需要一个共享访问点或共享数据:

例如一个Web页面上的计数器,可以不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的;

2.3、创建一个对象需要消耗的资源过多:

如要访问IO和数据库等资源;

2.4、日志系统:

在应用程序中,通常只需要一个日志系统,以避免在多个地方创建多个日志对象。这一般是由于共享的日志文件一直处于打开状态,所以只能有一个实例去操作,否则内容不好追加也有可能造成资源占用加剧资源消耗。

2.5、数据库连接池(长连接场景):

在应用程序中,数据库连接池是一个非常重要的资源,单例模式可以确保在应用程序中只有一个数据库连接池实例,避免资源浪费。主要是节省打开或者关闭数据库连接所引起的效率损耗,因为何用单例模式来维护,就可以大大降低这种损耗。

2.6、配置文件管理器:

在应用程序中,通常只需要一个配置文件管理器来管理应用程序的配置文件,单例模式可以确保在整个应用程序中只有一个配置文件管理器实例。这个是由于配置文件是共享的资源。

2.7、缓存系统:

在应用程序中,缓存系统是一个重要的组件,单例模式可以确保在整个应用程序中只有一个缓存实例,以提高应用程序的性能。

3、创建方式:

单例模式其结构主要分为三部分:

        私有化构造函数:防止外部直接实例化对象。

        私有静态成员变量:用于保存唯一的实例。

        公有静态方法:提供获取该实例的唯一访问点。

单例模式分为懒汉式和饿汉式

3.1 懒汉式:

类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建。

线程安全(双重检查锁)的懒汉式示例(对于lock不了解的照着用就行):

双重检查的意义:

要实现线程安全其实只用使用lock给静态全局变量加锁即可,这样多个线程同时访问会排队等待。但是当第一个线程进入锁后就已经实例化对象了,后续的线程就算排队进入了也会因为对象已经不为null直接跳出程序,这样看来后面的线程排队进入锁内其实啥事没干就出去了,这就会造成资源的浪费,故此在锁的外面再判断静态变量是否为空这样仅第一个线程需要进入锁内去实例化对象,后续线程可直接返回对象即可。

public class Singleton{//定义一个私有的静态全局变量来保存该类的唯一实例private static Singleton singleton;//线程锁private static readonly object _Object = new object();/// <summary>/// 私有构造函数/// </summary>private Singleton(){//必须是私有的构造函数,防止外部通过new来创建该类的实例。//想要使用该类只能通过唯一访问点GetInstance()。}/// <summary>/// 全局访问点/// 设置为静态方法则可在外边无需创建该类的实例就可调用该方法,当然你也可以使用属性作为全局访问点/// </summary>/// <returns></returns>public static Singleton GetInstance(){if (singleton == null)//第一重{lock (_Object){if (singleton == null)//第二重{singleton = new Singleton();}}}return singleton;}}

使用方法:Singleton singletonOne = Singleton.GetInstance();

全局访问点除了使用方法以外还可使用属性进行调用

public class Singleton
{//静态变量private static Singleton _instance;//锁private static readonly object _lock = new();//私有构造函数private Singleton(){}//外部访问属性public static Singleton Instance{get{//保证效率,实例化后不再进入lock块if (_instance == null){//确保线程安全lock (_lock){if (_instance == null){_instance = new Singleton();}}}//已经被实例化直接返回return _instance;}}}

 使用方法:Singleton.Instance;

3.2 饿汉式:

类加载就会导致该单实例对象被创建。

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

public class Singleton
{// 私有静态成员readonly private static readonly Singleton instance = new Singleton();// 私有构造函数,防止外部直接实例化private Singleton() {}// 公有静态属性,提供访问单例实例的唯一访问点public static Singleton Instance{get{return instance;}}
}

到此想必你也看出来懒汉式和饿汉式的区别了吧,说简单点就是懒汉式的实例化是再外部接口里的,饿汉式的实例化是直接实例化的。

3.3 Lazy方式

当然除了上面两种还有一种使用C#的Lazy来实现

public class Singleton
{//第一个参数是一个工厂方法,返回一个T实例且没有形参;第二个参数true代表需要保证线程安全,false表示不需要线程安全private static readonly Lazy<Singleton> _instance = new Lazy<Singleton>(() => new Singleton(),true);public static Singleton Instance { get => _instance.Value; }private Singleton(){}
}

到此就结束了,上面三种方式都是线程安全的可放心使用,至于不安全的写法相比也没人需要吧。。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA初探:深入理解 Structure 功能

一、Structure - 类视图 Structure 是 IDEA 中的一个视图工具&#xff0c;它提供了对当前文件中结构元素的快速访问。通过 Structure&#xff0c;我们可以方便地查看和导航到代码中的各个部分&#xff0c;从而提高代码编辑和浏览的效率。 1.1 基本概念 Structure 视图以树形结…

数据库文档插件 screw

pom 配置 <build><plugins><plugin><groupId>cn.smallbun.screw</groupId><artifactId>screw-maven-plugin</artifactId><version>1.0.5</version><dependencies><dependency><groupId>com.zaxxer<…

高效网络自动化:Python在网络基础中的应用

高效网络自动化&#xff1a;Python在网络基础中的应用 目录 &#x1f310; TCP/IP协议与网络层次模型&#x1f4bb; 使用socket编程实现网络通信&#x1f30d; HTTP协议与RESTful API的基本概念&#x1f4e1; 使用requests库进行HTTP请求和响应处理 1. &#x1f310; TCP/IP协…

数据结构-树

目录 概念 结点分类 根结点 结点的度&#xff08;De-gree&#xff09; 树的度 结点间关系 孩子&#xff08;Child&#xff09;、双亲&#xff08;Parent&#xff09; 兄弟&#xff08;Sibing&#xff09;、堂兄弟&#xff08;Cousins&#xff09; 祖先&#xff08;anc…

VAE中的“变分”什么

写在前面 VAE&#xff08;Variational Autoencoder&#xff09;&#xff0c;中文译为变分自编码器。其中AE&#xff08;Autoencoder&#xff09;很好理解。那“变分”指的是什么呢?—其实是“变分推断”。变分推断主要用在VAE的损失函数中&#xff0c;那变分推断是什么&#x…

C++ | Leetcode C++题解之第514题自由之路

题目&#xff1a; 题解&#xff1a; class Solution { public:int findRotateSteps(string ring, string key) {int n ring.size(), m key.size();vector<int> pos[26];for (int i 0; i < n; i) {pos[ring[i] - a].push_back(i);}vector<vector<int>>…

linux指令笔记

bash命令行讲解 lyt &#xff1a;是用户名 iZbp1i65rwtrfbmjetete2b2Z :这个是主机名 ~ &#xff1a;这个是当前目录 $ &#xff1a;这个是命令行提示符 每个指令都有不同的功能&#xff0c;大部分指令都可以带上选项来实现不同的效果。 一般指令和选项的格式&#xff1a;…

Linux 重启命令全解析:深入理解与应用指南

Linux 重启命令全解析&#xff1a;深入理解与应用指南 在 Linux 系统中&#xff0c;掌握正确的重启命令是确保系统稳定运行和进行必要维护的关键技能。本文将深入解析 Linux 中常见的重启命令&#xff0c;包括功能、用法、适用场景及注意事项。 一、reboot 命令 功能简介 re…

洛谷 P3130 [USACO15DEC] Counting Haybale P

原题链接 题目本质&#xff1a;线段树 感觉我对线段树稍有敏感&#xff0c;线段树一眼就看出来了&#xff0c;思路出来得也快&#xff0c;这道题也并不是很难。 解题思路&#xff1a; 这道题能看出来是线段树就基本成功一半了&#xff0c;区间修改区间查询&#xff0c;就基…

深入探索:深度学习在时间序列预测中的强大应用与实现

引言&#xff1a; 时间序列分析是数据科学和机器学习中一个重要的研究领域&#xff0c;广泛应用于金融市场、天气预报、能源管理、交通预测、健康监控等多个领域。时间序列数据具有顺序相关性&#xff0c;通常展示出时间上较强的依赖性&#xff0c;因此简单的传统回归模型往往…

使用微信免费的内容安全识别接口,UGC场景开发检测违规内容功能

大家好&#xff0c;我是小悟。 内容安全识别主要针对的是有UGC即用户生成内容的功能场景&#xff0c;通过结合内容安全的审核能力&#xff0c;应对文本、图片、音频内容类型下的敏感内容识别、涉黄内容识别、暴恐内容识别、辱骂内容识别等违规问题&#xff0c;可以提高审核效率…

【Docker大揭秘】

Docker 调试一天的血与泪的教训&#xff1a;设备条件&#xff1a;对应的build preparation相应的报错以及修改 作为记录 构建FASTLIO2启动docker获取镜像列出镜像运行containerdocker中实现宿主机与container中的文件互传 调试一天的血与泪的教训&#xff1a; 在DOCKER中跑通F…

ubuntu-开机黑屏问题快速解决方法

开机黑屏一般是由于显卡驱动出现问题导致。 快速解决方法&#xff1a; 通过ubuntu高级选项->recovery模式->resume->按esc即可进入recovery模式&#xff0c;进去后重装显卡驱动&#xff0c;重启即可解决。附加问题&#xff1a;ubuntu的默认显示管理器是gdm3,如果重…

海洋生物图像分割系统:算法改进策略

海洋生物图像分割系统源码&#xff06;数据集分享 [yolov8-seg-C2f-DiverseBranchBlock&#xff06;yolov8-seg-C2f-Faster-EMA等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目…

PHP-FPM 性能配置优化

4 核 8 G 服务器大约可以开启 500 个 PHP-FPM&#xff0c;极限吞吐量在 580 qps &#xff08;Query Per Second 每秒查询数&#xff09;左右。 Nginx php-fpm 是怎么工作的&#xff1f; php-fpm 全称是 PHP FastCGI Process Manager 的简称&#xff0c;从名字可得知&#xff…

第十七周:机器学习

目录 摘要 Abstract 一、MCMC 1、马尔科夫链采样 step1 状态设定 step2 转移矩阵 step3 马尔科夫链的生成 step4 概率分布的估计 2、蒙特卡洛方法 step1 由一个分布产生随机变量 step2 用这些随机变量做实验 3、MCMC算法 4、参考文章 二、flow-based GAN 1、引…

【Linux网络】Linux网络基础入门:初识网络,理解网络协议

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;Linux “ 登神长阶 ” &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀Linux网络 &#x1f4d2;1. 计算机网络背景发展历程"协议" &#x1f4dc;2. 网络协…

UML外卖系统报告(包含具体需求分析)

1、系统背景 随着互联网技术的快速发展&#xff0c;外卖订餐服务逐渐成为人们生活中的一部分。传统的电话订餐方式面临诸多不便和限制&#xff0c;而基于互联网的外卖订餐系统则提供了更加便捷、快速和高效的订餐服务。这种系统通过将餐厅、顾客和配送人员连接起来&#xff0c…

Sentinel详解

参考博客&#xff1a; SpringCloud Sentinel集成到微服务项目中&#xff08;保姆级教程&#xff09; 什么是Sentinel Sentinel 是面向分布式服务架构的轻量级流量控制产品&#xff0c;主要以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度来保护服务…

Vue学习记录之二十五 Vue3中Web Componets的使用

一、webcomponets介绍 在Vue 3中使用Web Components可以通过多种方式实现。Web Components是一组允许你创建可重用、封装良好的自定义元素的标准技术。它们包括Custom Elements、Shadow DOM、HTML Templates等。 Vue3 支持原生模式&#xff0c;可以让单个文件的js,css,html以h…