首页 > 编程语言 >【转】[C#] 单例模式

【转】[C#] 单例模式

时间:2024-03-22 17:44:23浏览次数:30  
标签:初始化 Singleton 检查 C# 模式 instance 实例 线程 单例

来自:阿里的 通义灵码

在C#中,单例模式实现线程安全时通常会采用双重检查锁定(Double-Checked Locking, DCL)的策略来确保只创建类的一个实例,并且这个过程是线程安全的。

两层lock的设计是为了减少获取锁的开销,尤其是当类的实例已经被初始化的情况下。

以下是一个使用双重检查锁定的C#单例模式示例:

public sealed class Singleton
{
    // 创建一个静态变量来保存唯一的 Singleton 实例。
    private static volatile Singleton instance;
    // 创建一个对象用于同步访问Singleton实例。
    private static object syncRoot = new Object();

    // 私有构造函数防止其他代码通过new关键字实例化。
    private Singleton() {}

    // 提供一个公共的静态方法来返回 Singleton 实例。
    public static Singleton Instance
    {
        get
        {
            // 第一层检查:如果实例已存在,则直接返回,无需加锁。
            if (instance != null)
            {
                return instance;
            }

            // 第二层检查:只有当第一次进入这里,即实例未被初始化时才需要加锁。
            lock (syncRoot)
            {
                // 在锁内再次检查实例是否已被另一个线程初始化。
                // 这是因为,在第一个if判断和进入lock之间可能存在竞态条件。
                if (instance == null)
                {
                    // 只有在这里创建实例。
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }
}

为什么需要两层检查?

  1. 性能优化
    • 第一次检查instance != null可以在不加锁的情况下完成,如果实例已经初始化,那么大多数情况下可以直接返回实例,避免了不必要的锁操作带来的性能损耗。
  2. 线程安全性
    • 如果多个线程同时发现实例尚未创建,而只有一个线程能够进入内部的lock块进行初始化。如果没有第二次检查,所有线程都会创建实例,导致违反单例原则。
    • 由于CLR的内存模型允许对象的构造和初始化顺序与指令执行顺序不同步,因此即使在多线程环境中,也需要在lock保护下进行实例化以保证线程安全。第二层检查确保了实例化操作仅执行一次。

总结来说,双重检查锁定的目的在于既保证了线程安全,又尽量减少了对锁的使用频率,从而提高了程序的并发性能。

标签:初始化,Singleton,检查,C#,模式,instance,实例,线程,单例
From: https://www.cnblogs.com/z5337/p/18090164

相关文章

  • NVIDIA的OpenUSD是什么? —— Universal Scene Description (USD)
    正如NVIDIA的老黄在2024年的技术大会上的展示一样,NVIDIA公司或许最准确的定义应该是计算机图形学公司,因为不论是NVIDIA搞GPU还是搞通用计算还是搞软件生态以至于现在搞AI搞机器人搞自动驾驶,其所有业务都是围绕图形图像学这条线来展开的。元宇宙,已经烂大街的一个概念,但是被业界认......
  • 2023-5-11-elasticsearch使用
    索引操作、数据操作索引操作索引的创建、删除等创建索引PUT/shopping{"acknowledged":true,"shards_acknowledged":true,"index":"shopping"}获取索引详细信息GET/_cat/indices?vhealthstatusindexuuid......
  • vue或react项目上线刷新出现404的原因以及解决办法
    问题描述:vue/react项目,正常的页面操作跳转,不会出现404的问题,但是一旦刷新,就会出现404报错。产生原因:我们打开vue/react打包后生成的dist文件夹,可以看到只有一个index.html文件及一些静态资源,这个是因为vue/react是单页应用(SPA),只有一个index.html作为入口文件,其它的路由都是通......
  • 2023-8-10-canal使用
    工作原理、mysql开启二进制日志、启动服务端、启动客户端工作原理canal模拟MySQLslave的交互协议,伪装自己为MySQLslave,向MySQLmaster发送dump协议MySQLmaster收到dump请求,开始推送binarylog给slave(即canal)canal解析binarylog对象(原始为byte流......
  • LRC软件、Adobe Lightroom Classic最新版破解安装下载合集教程
    AdobeLightroomClassic(简称LR)是AdobeCreativeCloud大家庭中的一款专业的图片管理和编辑工具,用于专业摄影师、摄影爱好者以及所有不断优化数码影像的人等。其目标是以丰富的功能提供高效、一致的体验,帮助用户汇聚、组织、管理、编辑和分享数码图片。AdobeLightroomClassi......
  • 2023-12-22-flink-cdc使用
    应用场景、上手体验应用场景FlinkCDC(ChangeDataCapture)是一种用于捕获和处理数据源中的变化的流处理技术。它可以实时地将数据源中的增量更新捕获到流处理作业中,使得作业可以实时响应数据变化。以下是FlinkCDC的一些常见应用场景:数据仓库和实时分析:FlinkCDC可以......
  • 深入了解C语言中浮点数的存储方式
    因为这期可能对你们来说太简单了,所以我用一个字来概括吧好了,结束了,我们下期再见喽,不会有人真的走了吧,好了,砸门多的不说少的不闹好吧,直接上主食。1.浮点数和整数在内存中存储的区别浮点数和整数在内存中存储的区别主要体现在数据表示和存储方式上:1.数据类型:  -整数(in......
  • CentOS7.9 搭建本地Yum源仓库
    一、背景        在公司的生产环境中,服务器一般处于内网,而我们想在这样的服务器上安装软件时会出现无法访问Internet从而导致依赖安装失败的问题,今天我们通过配置离线YUM源仓库来解决类似问题。二、查看系统版本[root@superset~]#cat/etc/redhat-releaseCentOS......
  • ASPNET MVC POST DELETE PUT 请求返回 400 (Bad Request)
    近日遇到 POSTDELETEPUT请求返回400(BadRequest),而GET请求正常的情况经几日排查,发现是【防止ASP.NETMVC应用程序中的跨站点请求伪造(CSRF)攻击】导致的解决方法:在请求头中加入 RequestVerificationToken@injectMicrosoft.AspNetCore.Antiforgery.IAntif......
  • Java版本spring cloud + spring boot企业电子招投标系统源代码
    招投标管理系统是一个集门户管理、立项管理、采购项目管理、采购公告管理、考核管理、报表管理、评审管理、企业管理、采购管理和系统管理于一体的综合性应用平台。它适用于招标代理、政府采购、企业采购和工程交易等业务的企业,旨在提高项目管理的效率和质量。该系统以项目为主......