前言

  设计模式的文章很多,所以此文章只是为了巩固一下自己的基础,说的不详细请见谅。

 介绍 - 单例模式

  官方定义:确保一个类只有一个实例,并提供一个全局访问点。

  通俗定义:就是一个类只有一个单个实例。(也没啥区别)

 实现

  如何保证一个类只有一个实例呢?

  1. 首先一个类是如何创建实例的? - 通过构造函数

  2. 如何保证只创建一个呢? - 构造函数只执行一次

  3. 如何保证构造函数只执行一次呢? - 访问外部类无权访问

  4. 如何让访问外部类无权访问? - 私有方法

  问题解决,上代码:

  1. /// <summary>
  2. /// 单例类
  3. /// </summary>
  4. public class Singleton
  5. {
  6. /// <summary>
  7. /// 私有构造函数
  8. /// </summary>
  9. private Singleton() { }
  10. /// <summary>
  11. /// 单例字段
  12. /// </summary>
  13. private static Singleton _instance;
  14. /// <summary>
  15. /// 单例对象
  16. /// </summary>
  17. public static Singleton Instance
  18. {
  19. get
  20. {
  21. if (_instance == null)
  22. _instance = new Singleton();
  23. return _instance;
  24. }
  25. }
  26.  
  27. /// <summary>
  28. /// 输出
  29. /// </summary>
  30. public void WriteLine()
  31. {
  32. Console.WriteLine("哈希Code : " + this.GetHashCode());
  33. }
  34. }

测试输出 HashCode :

  1.   class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. Singleton.Instance.WriteLine();
  6. Singleton.Instance.WriteLine();
  7. Singleton.Instance.WriteLine();
  8. Console.Read();
  9. }
  10. }

结果:

这样就结束了吗? -(身为C#老鸟的我还要考虑下线程安全的问题,考虑并发的情况)

我们需要构建一个并发的情形及多条线程同时创建对象,下面我就用简单粗暴的方法,需要对单例进行修改:

  1. /// <summary>
  2. /// 单例对象
  3. /// </summary>
  4. public static Singleton Instance
  5. {
  6. get
  7. {
  8. if (_instance == null)
  9. {
  10. Thread.Sleep();
  11. _instance = new Singleton();
  12. }
  13. return _instance;
  14. }
  15. }

调用测试:

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. //线程1
  6. Thread thread1 = new Thread(new ThreadStart(() =>
  7. {
  8. Singleton.Instance.WriteLine();
  9. }));
  10. //线程2
  11. Thread thread2 = new Thread(new ThreadStart(() =>
  12. {
  13. Singleton.Instance.WriteLine();
  14. }));
  15. //线程3
  16. Thread thread3 = new Thread(new ThreadStart(() =>
  17. {
  18. Singleton.Instance.WriteLine();
  19. }));
  20. thread1.Start();
  21. thread2.Start();
  22. thread3.Start();
  23. Console.Read();
  24. }
  25. }

输出结果:

所以我们要对代码进行改进(加锁):

  1. /// <summary>
  2. /// 单例类
  3. /// </summary>
  4. public class Singleton
  5. {
  6. /// <summary>
  7. /// 锁
  8. /// </summary>
  9. private static object locker = new object();
  10. /// <summary>
  11. /// 私有构造函数
  12. /// </summary>
  13. private Singleton() { }
  14. /// <summary>
  15. /// 单例字段
  16. /// </summary>
  17. private static Singleton _instance;
  18. /// <summary>
  19. /// 单例对象
  20. /// </summary>
  21. public static Singleton Instance
  22. {
  23. get
  24. {
  25. lock (locker)
  26. {
  27. if (_instance == null)
  28. {
  29. Thread.Sleep();
  30. _instance = new Singleton();
  31. }
  32. }
  33. return _instance;
  34. }
  35. }
  36.  
  37. /// <summary>
  38. /// 输出
  39. /// </summary>
  40. public void WriteLine()
  41. {
  42. Console.WriteLine("哈希Code : " + this.GetHashCode());
  43. }
  44. }

测试结果:

解决!

锁是个好东西但是要慎用,它是很耗资源的。所以还需要对代码进行改进,看代码我们知道只有 _instance 为 null 时才需要考虑并发加锁,所以我们再次改进:

  1. /// <summary>
  2. /// 单例类
  3. /// </summary>
  4. public class Singleton
  5. {
  6. /// <summary>
  7. /// 锁
  8. /// </summary>
  9. private static object locker = new object();
  10. /// <summary>
  11. /// 私有构造函数
  12. /// </summary>
  13. private Singleton() { }
  14. /// <summary>
  15. /// 单例字段
  16. /// </summary>
  17. private static Singleton _instance;
  18. /// <summary>
  19. /// 单例对象
  20. /// </summary>
  21. public static Singleton Instance
  22. {
  23. get
  24. {
  25. if(_instance == null)
  26. {
  27. lock (locker)
  28. {
  29. if (_instance == null)
  30. {
  31. Thread.Sleep();
  32. _instance = new Singleton();
  33. }
  34. }
  35. }
  36. return _instance;
  37. }
  38. }
  39.  
  40. /// <summary>
  41. /// 输出
  42. /// </summary>
  43. public void WriteLine()
  44. {
  45. Console.WriteLine("哈希Code : " + this.GetHashCode());
  46. }
  47. }

欢迎批评指正!转载请注明出处:http://www.cnblogs.com/xinwang/p/6294784.html

C# 设计模式巩固 - 单例模式的更多相关文章

  1. 设计模式之单例模式(Singleton)

    设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...

  2. GJM : C#设计模式(1)——单例模式

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  3. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  4. 每天一个设计模式-4 单例模式(Singleton)

    每天一个设计模式-4 单例模式(Singleton) 1.实际生活的例子 有一天,你的自行车的某个螺丝钉松了,修车铺离你家比较远,而附近的五金店有卖扳手:因此,你决定去五金店买一个扳手,自己把螺丝钉固 ...

  5. 设计模式之单例模式的简单demo

    /* * 设计模式之单例模式的简单demo */ class Single { /* * 创建一个本类对象. * 和get/set方法思想一样,类不能直接调用对象 * 所以用private限制权限 * ...

  6. 设计模式之单例模式——Singleton

                        设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...

  7. 10月27日PHP加载类、设计模式(单例模式和工厂模式)、面向对象的六大原则

    加载类可以使用include.require.require_once三种中的任意一种,每个关键字都有两种方法,但是这种方法的缺点是需要加载多少个php文件,就要写多少个加载类的方法.一般也就需要加载 ...

  8. java 23 - 2 设计模式之单例模式

    单例模式:保证类在内存中只有一个对象. 如何保证类在内存中只有一个对象呢?  A:把构造方法私有  B:在成员位置自己创建一个对象  C:通过一个公共的方法提供访问 单例模式之饿汉式: (一进来就造对 ...

  9. [转]JAVA设计模式之单例模式

    原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...

  10. python_way,day8 面向对象【多态、成员--字段 方法 属性、成员修饰符、特殊成员、异常处理、设计模式之单例模式、模块:isinstance、issubclass】

    python_way day8 一.面向对象三大特性: 多态 二.面向对象中的成员 字段.方法属性 三.成员修饰符 四.特殊成员 __init__.__doc__.__call__.__setitem ...

随机推荐

  1. POJ - 3308 Paratroopers (最小点权覆盖)

    题意:N*M个格点,K个位置会有敌人.每行每列都有一门炮,能打掉这一行(列)上所有的敌人.每门炮都有其使用价值.总花费是所有使用炮的权值的乘积.求最小的总花费. 若每门炮的权值都是1,就是求最小点覆盖 ...

  2. [Python]关于return逻辑判断和短路逻辑

    定义一个return...and..函数: def res(): ' 返回结果: >>> print(res()) 1234 定义一个return...or..函数: def res ...

  3. SVN文件版本太旧问题解决

    错误信息如下: E155036: The working copy at '/Users/...' is too old (format 10) to work with client version ...

  4. RPC细节

    服务化有什么好处? 服务化的一个好处就是,不限定服务的提供方使用什么技术选型,能够实现大公司跨团队的技术解耦,如下图所示: 服务A:欧洲团队维护,技术背景是Java 服务B:美洲团队维护,用C++实现 ...

  5. git的应用

    对git的应用 (终于第一次用会git) 根据胡东晖同学的博客(使用git推送代码到开源中国以及IDEA环境下使用git)与热心指导,自己跟着做了,虽然途中出了很多很多问题,但是好在最后还是成功了!! ...

  6. Oh My Zsh 插件篇 - 实用工具

    Oh My Zsh 除了为我们提供快捷的命令行操作之外,还提供了强大丰富的插件机制,每个社区贡献者都可以贡献自己的插件,让整个生态体系更加丰富完善.今天给大家介绍了一下它的实用工具类插件. 前面我们分 ...

  7. 4.9版本的linux内核中eeprom存储芯片at24c512的驱动源码在哪里

    答:drivers/misc/eeprom/at24.c,内核配置项为CONFIG_EEPROM_AT24 Location: -> Device Drivers -> Misc devi ...

  8. HTTP协议Keep-Alive模式详解和HTTP头字段总结

    1.什么是Keep-Alive模式? 我们知道HTTP协议采用“请求-应答”模式,当使用普通模式,即非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成 之后立即断开连接(HT ...

  9. 爬虫之Xpath案例

    案例:使用XPath的爬虫 现在我们用XPath来做一个简单的爬虫,我们尝试爬取某个贴吧里的所有帖子,并且将该这个帖子里每个楼层发布的图片下载到本地. # tieba_xpath.py #!/usr/ ...

  10. DataStage系列教程 (Change Capture)

    Change Capture可以比较具有相同列的数据集的差异,得出一个数据集(After)在另一个数据库(Before)的基础上产生的哪些变化.变化类型如表1: 变化代码 变化 中文说明 0 no c ...