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

.NET之C#编程:懒汉模式的终结,单例模式的正确打开方式

概述

在C#编程世界中,单例模式是一种常见的设计模式,用于确保一个类只有一个实例,并提供一个全局访问点。然而,传统的懒汉模式实现方式在多线程环境下存在安全隐患。本文将深入探讨单例模式的正确实现姿势,带你走出懒汉模式的误区,掌握单例模式的高级玩法。

单例的正确打开方式

一、单例模式的基本概念单例模式确保一个类在任何情况下都只有一个实例,并且提供一个全局访问点。这在配置管理、连接池等场景中非常有用。

二、懒汉模式的陷阱懒汉模式在第一次调用GetInstance方法时才会创建实例,看起来简单,但在多线程环境下,可能会创建多个实例。

 
public class LazySingleton
{private static LazySingleton instance;private LazySingleton() { }public static LazySingleton GetInstance(){if (instance == null){instance = new LazySingleton();}return instance;}
}

使用场景:单例实例在多线程访问前不需要初始化。优点:延迟加载,节省资源。缺点:多线程环境下不安全。

三、线程安全的懒汉模式通过lock关键字确保线程安全,但这种方式存在性能瓶颈。

 
private static readonly object lockObject = new object();
public static Singleton GetInstance()
{if (instance == null){lock (lockObject){if (instance == null){instance = new Singleton();}}}return instance;
}

使用场景:需要确保线程安全的单例。优点:线程安全。缺点:性能开销大。

四、静态初始化器的单例模式C#的静态初始化器是线程安全的,并且不需要使用lock,这是实现单例模式的一种简洁方式。

 
public class StaticInitializerSingleton
{private static readonly StaticInitializerSingleton instance = new StaticInitializerSingleton();private StaticInitializerSingleton() { }public static StaticInitializerSingleton GetInstance(){return instance;}
}

使用场景:适用于大多数单例模式需求。优点:简洁,线程安全。缺点:实例在类加载时就创建,无法延迟加载。

五、使用Singleton属性通过一个静态只读属性来实现单例,这种方式同样利用了静态初始化的线程安全性。

 
public class ReadOnlySingleton
{private static readonly ReadOnlySingleton instance = new ReadOnlySingleton();private ReadOnlySingleton() { }public static ReadOnlySingleton Instance { get { return instance; } }
}

使用场景:需要通过属性访问单例实例。优点:简洁,线程安全。缺点:同静态初始化器。

六、双重检查锁定模式双重检查锁定模式是懒汉模式的一个改进,它既保证了线程安全,又避免了不必要的锁。

 
public class DoubleCheckedLockingSingleton
{private static readonly object lockObject = new object();private static DoubleCheckedLockingSingleton instance;public static DoubleCheckedLockingSingleton GetInstance(){if (instance == null){lock (lockObject){if (instance == null){instance = new DoubleCheckedLockingSingleton();}}}return instance;}
}

使用场景:需要延迟加载的单例,且要求线程安全。优点:线程安全,延迟加载。缺点:代码复杂。

七、使用静态构造函数静态构造函数在类首次加载时执行,可以用来初始化静态成员,但这种方式不支持延迟加载。

 
public class StaticConstructorSingleton
{private static readonly StaticConstructorSingleton instance;static StaticConstructorSingleton(){instance = new StaticConstructorSingleton();}private StaticConstructorSingleton() { }public static StaticConstructorSingleton GetInstance(){return instance;}
}

使用场景:类加载时需要初始化的单例。优点:线程安全,无需手动同步。缺点:不支持延迟加载。

八、总结单例模式的实现方式多种多样,每种方式都有其适用场景和优缺点。在实际开发中,我们应该根据具体需求选择合适的实现方式。对于大多数情况,推荐使用静态初始化器的方式,因为它简洁且线程安全。如果需要延迟加载,可以考虑使用双重检查锁定模式。

结语:单例模式是C#编程中的经典模式,正确实现单例模式不仅可以保证程序的稳定性,还可以提高代码的可维护性。希望通过本文的探讨,能够帮助大家避免使用懒汉模式,掌握单例模式的正确实现方式,写出更加优雅、高效的代码。

往期精品推荐:

在国内默默无闻的.NET,在国外火的超乎想象?

C#的膨胀之路:创新还是灭亡

介绍.NET 6款好看的winform开源UI库

介绍一款最受欢迎的.NET 开源UI库

WPF第三方开源UI框架:打造独特体验的魔法师

WPF与Winform,你的选择是?

WinForm的前世今生

.NET成年了,然后呢?——编程界的逆袭传奇

相关文章:

  • AI为小微企业赋能:解锁数字化转型的金钥匙
  • PHP护照识别API、护照识别设备
  • 在低版本Excel中创建次级下拉列表
  • 1、音视频解封装流程---解复用
  • 软件测试基础知识总结
  • 如何使用PHP Curl类库编写高效的爬虫程序?
  • VUE自定义新增、复制、删除dom元素
  • LLM应用:传统NLP任务
  • H5项目使用vant组件的手机号校验
  • 常用字符串方法<python>
  • Spring Boot中的日志管理最佳实践
  • 2.2.4 C#中显示控件BDPictureBox 的实现----ROI交互
  • windows@无密码的本地用户账户相关问题@仅用用户名免密登录远程桌面登录和控制@无密码用户访问共享文件夹以及挂载问题
  • 【分布式系统】监控平台Zabbix对接grafana
  • 探讨命令模式及其应用
  • [ JavaScript ] 数据结构与算法 —— 链表
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • Angular 响应式表单之下拉框
  • Asm.js的简单介绍
  • IP路由与转发
  • Javascript Math对象和Date对象常用方法详解
  • Java比较器对数组,集合排序
  • Java知识点总结(JavaIO-打印流)
  • JS专题之继承
  • Objective-C 中关联引用的概念
  • SpiderData 2019年2月13日 DApp数据排行榜
  • SpringBoot几种定时任务的实现方式
  • Vue--数据传输
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 从输入URL到页面加载发生了什么
  • 聊聊flink的BlobWriter
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 前嗅ForeSpider教程:创建模板
  • 使用 Docker 部署 Spring Boot项目
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 智能合约开发环境搭建及Hello World合约
  • #define MODIFY_REG(REG, CLEARMASK, SETMASK)
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (附源码)计算机毕业设计ssm电影分享网站
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (函数)颠倒字符串顺序(C语言)
  • (三)uboot源码分析
  • (实战篇)如何缓存数据
  • (一)基于IDEA的JAVA基础1
  • (转)人的集合论——移山之道
  • **PHP二维数组遍历时同时赋值
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .NET 4.0中的泛型协变和反变
  • .NET 8.0 中有哪些新的变化?
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .net core 控制台应用程序读取配置文件app.config
  • .Net Core与存储过程(一)
  • @KafkaListener注解详解(一)| 常用参数详解
  • @RequestMapping 的作用是什么?
  • @拔赤:Web前端开发十日谈