C#中单例模式CSingleton

打印 上一主题 下一主题

主题 1118|帖子 1118|积分 3354

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在 C# 中,单例模式是一种设计模式,确保一个类只有一个实例,并提供全局访问点。单例模式常用于必要全局共享某个资源或对象的场景,如数据库连接、日志记载器等。
懒汉式(Lazy Initialization)单例模式

这种方式下,实例只会在第一次必要的时候创建,并且使用 lock 关键字来保证线程安全。
  1. public class Singleton
  2. {
  3.     // 静态变量保存单例实例
  4.     private static Singleton instance = null;
  5.     // 静态锁对象,用于确保线程安全
  6.     private static readonly object lockObj = new object();
  7.     // 私有构造函数,防止外部实例化
  8.     private Singleton()
  9.     {
  10.     }
  11.     // 公共静态方法,用于获取单例实例
  12.     public static Singleton Instance
  13.     {
  14.         get
  15.         {
  16.             // 双重检查锁定(Double-checked Locking)
  17.             if (instance == null)
  18.             {
  19.                 lock (lockObj)
  20.                 {
  21.                     if (instance == null)
  22.                     {
  23.                         instance = new Singleton();
  24.                     }
  25.                 }
  26.             }
  27.             return instance;
  28.         }
  29.     }
  30.     // 示例方法
  31.     public void DoSomething()
  32.     {
  33.         Console.WriteLine("Singleton is working.");
  34.     }
  35. }
复制代码
饿汉式(Eager Initialization)单例模式

  1. public class Singleton
  2. {
  3.     // 静态变量保存单例实例,并在类加载时创建实例
  4.     private static readonly Singleton instance = new Singleton();
  5.     // 私有构造函数,防止外部实例化
  6.     private Singleton()
  7.     {
  8.     }
  9.     // 公共静态方法,用于获取单例实例
  10.     public static Singleton Instance
  11.     {
  12.         get
  13.         {
  14.             return instance;
  15.         }
  16.     }
  17.     // 示例方法
  18.     public void DoSomething()
  19.     {
  20.         Console.WriteLine("Singleton is working.");
  21.     }
  22. }
复制代码
两种单例模式的使用都是一样的:
  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         Singleton singleton = Singleton.Instance;
  6.         singleton.DoSomething();  // 输出:Singleton is working.
  7.     }
  8. }
复制代码
使用 Lazy 实现懒加载的线程安全单例

C# 中有一个内置的 Lazy<T> 类型,专门用于实现懒加载。使用它可以大大简化懒汉式单例的实现,并且它自带线程安全。
  1. public class Singleton
  2. {
  3.     // 使用 Lazy<T> 实现线程安全的懒加载
  4.     private static readonly Lazy<Singleton> lazyInstance = new Lazy<Singleton>(() => new Singleton());
  5.     // 私有构造函数,防止外部实例化
  6.     private Singleton()
  7.     {
  8.     }
  9.     // 公共静态方法,用于获取单例实例
  10.     public static Singleton Instance
  11.     {
  12.         get
  13.         {
  14.             return lazyInstance.Value;
  15.         }
  16.     }
  17.     // 示例方法
  18.     public void DoSomething()
  19.     {
  20.         Console.WriteLine("Singleton is working.");
  21.     }
  22. }
复制代码
单例模式的使用场景

单例模式常用于以下场景:

  • 全局管理资源:如数据库连接池、日志记载器等全局共享的资源。
  • 设置管理:某些应用步伐全局设置只必要一个实例,例如读取设置文件。
  • 线程池:用于管理线程的全局共享资源。
  • 缓存:假如应用步伐必要缓存一些数据,全局缓存管理器通常是一个单例。
优缺点

长处:
内存优化:确保只创建一个实例,节省系统资源。
全局访问:可以通过全局访问点获取实例,方便管理全局状态。
缺点:
潜伏依赖:使用单例模式时,全局状态可能变得不透明,导致代码难以测试和维护。
并发题目:假如单例对象负责多线程利用,必须保证线程安全,否则轻易引发并发题目。
两种单例模式的区别

选择 懒汉式 还是 饿汉式 单例模式取决于具体的需求和场景,尤其是应用步伐的性能、资源管理以及线程安全的考虑。
懒汉式单例(Lazy Initialization)

第一次必要时才会创建实例,通常使用 lock 机制来保证线程安全。以下是适合使用懒汉式单例的场景:
适用场景:


  • 资源斲丧大:假如实例的创建过程非常耗费资源(如必要加载大量数据或进行复杂的盘算),那么使用懒汉式更为合适。这样可以避免在步伐启动时就斲丧大量资源,只有在必要使用时才初始化对象。
  • 不确定实例是否会被使用:假如有可能该实例在步伐的生命周期内不肯定会被用到,那么使用懒汉式可以避免在步伐启动时创建不必要的实例。例如,某个功能模块可能只在特定条件下才会被使用。
  • 延长加载优化:在某些场景下,延长加载(Lazy Loading)有助于优化启动时间,避免过早加载未使用的对象,这可以提升步伐启动性能。
    长处
  • 避免不必要的资源斲丧。
  • 按需加载,提升启动性能。
    缺点:
  • 实现稍微复杂,必要使用双重查抄锁定(Double-Checked Locking)来确保线程安全。
  • 在多线程环境中可能增加锁定带来的开销,尤其是访问频仍时。
饿汉式单例(Eager Initialization)

饿汉式单例是在类加载时立刻创建实例,且是线程安全的,由于 .NET 运行时会确保静态字段的初始化是线程安全的。
适用场景:


  • 创建实例开销小:假如单例实例的创建过程不会斲丧太多资源,并且实例总是会被使用,那么饿汉式是更为合适的选择。这样可以简化实现,不必要进行线程同步处理处罚。
  • 确定实例总是会被使用:假如你知道该单例类在应用步伐中肯定会被使用,并且尽早创建实例有助于进步性能,那么使用饿汉式更为合适。例如,某些全局的设置管理器、日志系统等全局资源通常在应用步伐启动时就必要初始化。
  • 必要线程安全且没有复杂的初始化逻辑:饿汉式的实现天然是线程安全的,且避免了懒汉式中为确保线程安全而引入的锁定开销。
    长处:
  • 实现简单,不必要考虑线程同步题目。
  • 无需延长加载,适用于那些步伐一启动就会使用到的单例对象。
    缺点:
  • 纵然不必要使用该实例,也会在步伐启动时占用资源,可能造成浪费。
  • 假如实例创建过程比力复杂,可能会影响步伐的启动速度。
场景/因素懒汉式单例饿汉式单例资源斲丧创建实例开销较大时优先选择创建实例开销小可以考虑使用使用频率可能不肯定使用单例,按需创建实例确定会使用单例,在步伐启动时就创建实例步伐启动性能步伐启动时不创建单例,避免影响启动性能步伐启动时创建实例,可能影响启动速度线程安全必要考虑线程安全,通常必要加锁线程安全由静态初始化机制自动保证实现复杂度必要更复杂的代码布局,双重查抄锁定等实现简单,直接在类加载时创建实例 总的来说:
懒汉式 适用于 资源斲丧较大且不确定是否会使用 的单例实例,能够在必要时才进行创建,避免资源浪费。
饿汉式 适用于 资源斲丧较小且确定肯定会使用 的单例实例,能够简化实现,提升线程安全性。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

笑看天下无敌手

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表