请选择 进入手机版 | 继续访问电脑版

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

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#问题入口 ASP.NET问题入口

【C#问题提交】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接毕业设计】 面试-葵花宝典下载

官方一群:

官方二群:

查看: 455|回复: 0

c#设计模式之单例模式

[复制链接]
  • TA的每日心情
    开心
    前天 21:32
  • 签到天数: 1610 天

    [LV.Master]伴坛终老

    4251

    主题

    6177

    帖子

    11万

    积分

    管理员

    IBC编程社区-原道楠

    Rank: 9Rank: 9Rank: 9

    积分
    111382

    推广达人突出贡献优秀版主荣誉管理论坛元老

    发表于 2019-11-8 09:49:44 | 显示全部楼层 |阅读模式

    马上加入IBC,查看更多教程

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

    x

    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编程社区
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则