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

C#单例模式

  单例模式 (Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。

通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化对个对象,一个最好的办法就是,让类自身负责保护它的唯一实例。这个类可以保证没有其他实例可以被创建。并且它可以提供一个访问该实例的方法。
在这里插入图片描述

   Singleton类,定义一个GetInstance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要是负责创建自己的唯一实例。

class Singleton
{
    private static Singleton instance;
    //构造方法让其private 这就堵死了外界利用new创建此类实例的可能
    private Singleton()
    {
    }
    //此方法是获得本类实例的唯一全局访问点
    public static Singleton GetInstance()
    {
        if (instance == null) //若实例不存在,则New一个新实例,否则返回已有的实例
        {
            instance = new Singleton();
        }
        return instance;
    }
}

客户端代码:

 static void Main(string[] args)
 {
     Singleton s1 = Singleton.GetInstance();
     Singleton s2 = Singleton.GetInstance();
     if (s1 == s2) //比较两次实例化后对象的结果是实例相同的
     {
         Console.WriteLine("两个对象是相同的实例");
     }
     Console.ReadKey();
 }

单例模式的好处:
1、可以保证唯一的实例。
2、可以严格地控制客户怎样访问它以及何时访问它。简单地说就是对唯一实例的受控访问。
单例模式与实用类的静态方法区别:
1、实用类不保存状态,仅提供一些静态方法或静态属性让你使用。
单例虽然实例唯一,却是可以有子类来继承。
2、实用类是一些方法属性的集合,单例是有着唯一的对象实例。
二、多线程时的单例
在多线程程序中,注意是同时访问Singleton类,调用GetInstance()方法,会可能造成创建多个实例的。这个时候可以给进程加一把锁来处理。
lock语句: lock是确保当一个线程位于代码的临界区时,另一个线程不进入临界区,如果其他线程试图进入锁定的代码,则它已知等待(即被阻止),指导该对象被释放。

 class Singleton
 {
     private static Singleton instance;
     //程序运行时创建一个静态只读的进程辅助对象
     private static readonly object syncRoot = new object();
     //构造方法让其private 这就堵死了外界利用new创建此类实例的可能
     private Singleton()
     {
     }
     //此方法是获得本类实例的唯一全局访问点
     public static Singleton GetInstance()
     {
         lock (syncRoot)//在同一时刻加了锁的那部分程序只有一个线程可以进入
         {
             if (instance == null) //若实例不存在,则New一个新实例,否则返回已有的实例
             {
                 instance = new Singleton();
             }
         }

         return instance;
     }

}
这段代码使得对象实例由最先进入的那个线程创建,以后的线程在进入时不再去创建对象实例了。由于有了lock,就保证了多线程环境下的同时访问也不会造成多个实例的生产。
三、双重锁定
如果上面每次调用GetInstance方法时都需要lock,这样做法会影响性能,所以可以双重锁定。

 public static Singleton GetInstance()
 {
     //先判断实例是否存在,不存在在加锁.
     if (instance == null)
     {

         lock (syncRoot)
         {

             if (instance == null)
             {
                 instance = new Singleton();
             }
         }
     }
     return instance;
 }

现在这样,我们不用让线程每次都加锁了,而只是在实例未被创建的时候再加锁处理。同时也保证多线程的安全。这种做法被称为Double-Check Locking(双重锁定)。

相关文章:

  • 常考计算机操作系统面试习题(二)(中)
  • Windows——电脑无法正常上网的一种解决办法
  • 统计学重要概念:自由度
  • 《Python实战进阶》第43集:使用 asyncio 实现异步编程
  • Amdahl 定律
  • react 中 key 的使用
  • 抗积分饱和(Anti-Windup)常见的处理方法
  • SpringBoot原理篇-SpringBoot配置优先级-Bean管理-起步依赖原理-自动配置两种方案-源码跟踪-自定义starter
  • 不同的CMS系统开源许可证对二次开发有哪些具体的限制?
  • 运维面试题(七)
  • 【矩阵快速幂】 P10502 Matrix Power Series|省选-
  • 蓝桥杯 之 最短路径算法
  • Bulk Rename Utility(BRU)——大批量重命名实用程序
  • NLP高频面试题(九)——大模型常见的几种解码方案
  • 图解AUTOSAR_CP_DiagnosticLogAndTrace
  • 深入解析 Redis 实现分布式锁的最佳实践
  • 京东二面:DeepSeek为何要用FP8而不是INT8?
  • spring boot 登入权限RBAC模式
  • 性能优化:python中的状态机
  • LLM - RAG性能的胜负手_重排序(Rerank)
  • 巴菲特再谈投资日本:希望持有日本五大商社至少50年
  • 郭少雄导演逝世,享年82岁
  • 在“蟑螂屋”里叠衣服,我看见人生百态
  • 魔都眼|西岸国际咖啡生活节:连接艺术、音乐与宠物
  • 戴上XR头盔,五一假期在上海也能体验“登陆月球”
  • 中国代表:美“对等关税”和歧视性补贴政策严重破坏世贸规则