马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#技术求助 ASP.NET技术求助

【源码下载】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接外包项目】 面试-葵花宝典下载

官方一群:

官方二群:

c#设计模式之单例模式

[复制链接]
查看2219 | 回复0 | 2019-11-8 09:49:44 | 显示全部楼层 |阅读模式

c#计划模式之单例模式

场景形貌

单例模式对于我们来说一点也不模式,是一个常见的名称,单例模式在步调中的实际效果就是:确保一个步调中只有一个实例,并提供一个全局访问点,节省系统资源

单例模式无论是在实际开发中还是在软件应用中比力常见,比如,windows系统的使命管理器、IIS的HttpApplication、实际项目中的日记组件等等

实现方式

  单例模式为了实现一个实例,那么只有不把实例创建袒暴露去,只通过类自己来创建实例,为了实现效果,必要界说一个私有构造函数

  单例模式实现方式有:饿汉式、懒汉式、双重验证式、静态内部类、耽误加载(Lazy)

  下面分别对每一种实现方式做一个简单的实例,以及其优缺点

  饿汉式

  1. /// <summary>
  2. /// 创建一个 Singleton 类(饿汉式)
  3. /// 这种方式比力常用,但容易产生垃圾对象。
  4. ///优点:没有加锁,实验效率会进步。
  5. ///缺点:类加载时就初始化,浪费内存。
  6. ///它基于 classloder 机制避免了多线程的同步标题,不外,instance 在类装载时就实例化,
  7. ///固然导致类装载的缘故因由有许多种,在单例模式中大多数都是调用 getInstance 方法,
  8. ///但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时间初始化 instance 显然没有到达 lazy loading 的效果。
  9. /// </summary>
  10. public class SingleObject
  11. {
  12. //创建 SingleObject 的一个对象
  13. private static SingleObject instance = new SingleObject();
  14. //让构造函数为 private,如许该类就不会被实例化
  15. private SingleObject() {
  16. Console.WriteLine("我被创建了.饿汉式");
  17. }
  18. //获取唯一可用的对象
  19. public static SingleObject GetInstance()
  20. {
  21. return instance;
  22. }
  23. public void ShowMessage()
  24. {
  25. Console.WriteLine("Hello World.饿汉式");
  26. }
  27. }
复制代码

  懒汉式

  

  1. /// <summary>
  2. /// 创建一个 Singleton 类(懒汉式)
  3. /// 这种方式具备很好的 lazy loading,可以或许在多线程中很好的工作,但是,效率很低,99% 环境下不必要同步。
  4. /// 优点:第一次调用才初始化,避免内存浪费。
  5. /// 缺点:懒汉式在单个线程中没有标题,但多个线程同事访问的时间就大概同事创建多个实例,而且这多个实例不是同一个对象。
  6. /// </summary>
  7. public class SingleObject1
  8. {
  9. //创建 SingleObject 的一个对象
  10. private static SingleObject1 instance;
  11. //让构造函数为 private,如许该类就不会被实例化
  12. private SingleObject1() { }
  13. //获取唯一可用的对象
  14. public static SingleObject1 GetInstance()
  15. {
  16. if (instance == null)
  17. {
  18. instance = new SingleObject1();
  19. Console.WriteLine("我被创建了.懒汉式");
  20. }
  21. return instance;
  22. }
  23. public void ShowMessage()
  24. {
  25. Console.WriteLine("Hello World.懒汉式");
  26. }
  27. }
复制代码

  双重验证式

  1. /// <summary>
  2. /// 创建一个 Singleton 类(双重验证)
  3. /// 这种方式具备很好的 lazy loading,可以或许在多线程中很好的工作,但是,效率很低,99% 环境下不必要同步。
  4. /// 优点:第一次调用才初始化,避免内存浪费,线程安全。
  5. /// 缺点:必须加锁 synchronized 才华包管单例,但加锁会影响效率。
  6. /// </summary>
  7. public class SingleObject2
  8. {
  9. //创建 SingleObject 的一个对象
  10. private static SingleObject2 instance;
  11. // 界说一个标识确保线程同步
  12. private static readonly object locker = new object();
  13. //让构造函数为 private,如许该类就不会被实例化
  14. private SingleObject2() { }
  15. //获取唯一可用的对象
  16. public static SingleObject2 GetInstance()
  17. {
  18. //// 假如为空,那么就加锁,创建实例
  19. if (instance == null)
  20. {
  21. lock (locker)
  22. {
  23. //// 枷锁乐成后,在做一次非空判定,避免在加锁期间以创建了实例而导致重复创建
  24. if (instance == null)
  25. {
  26. instance = new SingleObject2();
  27. Console.WriteLine("我被创建了.双重验证");
  28. }
  29. }
  30. }
  31. return instance;
  32. }
  33. public void ShowMessage()
  34. {
  35. Console.WriteLine("Hello World.双重验证");
  36. }
  37. }
复制代码

  静态内部类

  

  1. /// <summary>
  2. /// 创建一个 Singleton 类(静态内部类)
  3. /// 这种方式不消加锁,在效率上和内存利用上都比力良好
  4. /// 降服了饿汉模式的不敷饿汉模式实验效率高,由于在类加载的时间初始化导致内存浪费
  5. /// </summary>
  6. public class SingletonStatic
  7. {
  8. /// <summary>
  9. /// 内部类
  10. /// </summary>
  11. public class SingletonStaticInner
  12. {
  13. /// <summary>
  14. /// 当一个类有静态构造函数时,它的静态成员变量不会被beforefieldinit修饰
  15. /// 就会确保在被引用的时间才会实例化,而不是步调启动的时间实例化
  16. /// </summary>
  17. static SingletonStaticInner() { }
  18. /// <summary>
  19. /// 实例化
  20. /// </summary>
  21. internal static SingletonStatic singletonStatic = new SingletonStatic();
  22. }
  23. /// <summary>
  24. /// 私有构造函数
  25. /// </summary>
  26. private SingletonStatic() {
  27. Console.WriteLine("我被创建了.静态内部类");
  28. }
  29. /// <summary>
  30. /// 获取实例
  31. /// </summary>
  32. /// <returns></returns>
  33. public static SingletonStatic GetInstance()
  34. {
  35. return SingletonStaticInner.singletonStatic;
  36. }
  37. public void ShowMessage()
  38. {
  39. Console.WriteLine("Hello World.静态内部类");
  40. }
  41. }
复制代码

  耽误加载(Lazy)

  

  1. /// <summary>
  2. /// 创建一个 Singleton 类(Lazy)
  3. /// 该方式是必要.netformwork4+
  4. /// </summary>
  5. public class SingletonLazy
  6. {
  7. private static Lazy<SingletonLazy> singletonLazy = new Lazy<SingletonLazy>(()=>new SingletonLazy());
  8. /// <summary>
  9. /// 私有构造函数
  10. /// </summary>
  11. private SingletonLazy()
  12. {
  13. Console.WriteLine("我被创建了.Lazy");
  14. }
  15. /// <summary>
  16. /// 获取实例
  17. /// </summary>
  18. /// <returns></returns>
  19. public static SingletonLazy GetInstance()
  20. {
  21. return singletonLazy.Value;
  22. }
  23. public void ShowMessage()
  24. {
  25. Console.WriteLine("Hello World.Lazy");
  26. }
  27. }
复制代码

  每一种创建方式测试

  创建一个控制台步调,通过多线程对每一种实现方式利用,检察实在例次数分析:

  1. /*
  2. 先容
  3. 意图:包管一个类仅有一个实例,并提供一个访问它的全局访问点。
  4. 告急解决:一个全局利用的类频繁地创建与烧毁。
  5. 何时利用:当您想控制实例数目,节省系统资源的时间。
  6. 怎样解决:判定系统是否已经有这个单例,假如有则返回,假如没有则创建。
  7. 关键代码:构造函数是私有的。
  8. 应用实例:
  9. 范例的已有应用:
  10. 1、windows的使命管理器等
  11. 2、IIS的HttpApplication,全部的HttpModule都共享一个HttpApplication实例
  12. 在项目中的实际利用场景:
  13. 1、日记组件
  14. 2、多线程线程池管理
  15. 3、网站计数器
  16. 4、设置文件管理
  17. */
  18. class Program
  19. {
  20. static void Main(string[] args)
  21. {
  22. TaskFactory taskFactory = new TaskFactory();
  23. List<Task> taskList = new List<Task>();
  24. //// 测试--饿汉式
  25. for (int i = 0; i < 5; i++)
  26. {
  27. taskList.Add(taskFactory.StartNew(() =>
  28. {
  29. SingleObject.GetInstance();
  30. }));
  31. }
  32. //// 测试--懒汉式
  33. for (int i = 0; i < 5; i++)
  34. {
  35. taskList.Add(taskFactory.StartNew(() =>
  36. {
  37. SingleObject1.GetInstance();
  38. }));
  39. }
  40. //// 测试--双重验证
  41. for (int i = 0; i < 5; i++)
  42. {
  43. taskList.Add(taskFactory.StartNew(() =>
  44. {
  45. SingleObject2.GetInstance();
  46. }));
  47. }
  48. //// 测试--静态内部类
  49. for (int i = 0; i < 5; i++)
  50. {
  51. taskList.Add(taskFactory.StartNew(() =>
  52. {
  53. SingletonStatic.GetInstance();
  54. }));
  55. }
  56. //// 测试--Lazy
  57. for (int i = 0; i < 5; i++)
  58. {
  59. taskList.Add(taskFactory.StartNew(() =>
  60. {
  61. SingletonLazy.GetInstance();
  62. }));
  63. }
  64. Console.ReadLine();
  65. }
  66. }
复制代码

运行效果:

095430byj9hhxrfsuj9rnj.png
  

总结

 根据单例模式是每一种实现方式对比分析,在实际利用过程中:发起接纳耽误加载(Lazy)

 固然,尚有其他雷同的实现单例的方式,没有写到的,也接待大家一起互换,勿喷

C#论坛 www.ibcibc.com IBC编程社区
C#
C#论坛
IBC编程社区
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则