一、单例模式简介

单例模式是为保证一个对象,在程序运行的任何时刻只有一个实例存在,我们把这种实现方式称之为“单例模式”。

二、单例模式的核心

单例类只有一个实例存在

单例类提供一个全局访问点

单例类通过自己创建唯一实例

单例类对外所有访问对象都提供一个唯一实例。

三、单例模式的优点

1、在程序运行中只有一个实例,减少内存占用,减少频繁的创建和销毁实例所带来的系统开销,

2、避免资源的多种无效占用

单例模式缺点:

没有接口 不能继承

四、单例模式应用场景

当一个事物在特定的环境中,只会存在一个实例时,我们可以采用单例模式对其进行设计。

例: 数据库连接池,计算机注册表 一个国家只有一个总统 日志系统中的日志文件 计算机中的打印池 计算机设备管理器

生成唯一序列号 网站计数器

五、单例模式的实现方式

1、非线程安全(尽量不要用)

  1. public sealed class Singleton
  2.  
  3. {
  4.  
  5. private static Singleton instance=null;
  6.  
  7. private Singleton()
  8.  
  9. {
  10.  
  11. }
  12.  
  13. public static Singleton Instance
  14.  
  15. {
  16.  
  17. get
  18.  
  19. {
  20.  
  21. if (instance==null)
  22.  
  23. {
  24.  
  25. instance = new Singleton();
  26.  
  27. }
  28.  
  29. return instance;
  30.  
  31. }
  32.  
  33. }
  34.  
  35. }

说明:上面的方法是非线程安全的,2个不同的线程可以同时进入这个方法,如果instance为空的并且这里返回真的情况下,都可以创建实例,这显然违反了单例模式,实际上,在测试以前,实例就已经有可能被创建了,

但是内存模型不能保证这个实例能被其他的线程看到,除非合适的内存屏障已经被跨过了。

2、简单的线程安全

  1. public sealed class Singleton
  2.  
  3. {
  4.  
  5. private static Singleton instance = null;
  6.  
  7. private static readonly object padlock = new object();
  8.  
  9. Singleton()
  10.  
  11. {
  12.  
  13. }
  14.  
  15. public static Singleton Instance
  16.  
  17. {
  18.  
  19. get
  20.  
  21. {
  22.  
  23. lock (padlock)
  24.  
  25. {
  26.  
  27. if (instance == null)
  28.  
  29. {
  30.  
  31. instance = new Singleton();
  32.  
  33. }
  34.  
  35. return instance;
  36.  
  37. }
  38.  
  39. }
  40.  
  41. }
  42.  
  43. }

上述实现是线程安全的。这个线程在共享的object上取出了一把锁,然后在创建实例以前检查这个实例是否被创建了。

这个保护了内存屏障问题(lock保证了所有的读取操作是在LOCK获得以后发生的,所有的unlock保证了所有的写操作在lock 释放以后发生的),这样就保证了一个线程只能创建一个实例(每次只有一个线程在这段代码中运行),不巧的是,性能上来说,锁变成了每次都必须的当这个实例被响应的时候。

3、尝试线程安全(双重锁定)不推荐使用

  1. public sealed class Singleton
  2.  
  3. {
  4.  
  5. private static Singleton instance = null;
  6.  
  7. private static readonly object padlock = new object();
  8.  
  9. Singleton()
  10.  
  11. {
  12.  
  13. }
  14.  
  15. public static Singleton Instance
  16.  
  17. {
  18.  
  19. get
  20.  
  21. {
  22.  
  23. if (instance == null)
  24.  
  25. {
  26.  
  27. lock (padlock)
  28.  
  29. {
  30.  
  31. if (instance == null)
  32.  
  33. {
  34.  
  35. instance = new Singleton();
  36.  
  37. }
  38.  
  39. }
  40.  
  41. }
  42.  
  43. return instance;
  44.  
  45. }
  46.  
  47. }
  48.  
  49. }

4、不完全lazy,但是线程安全且不用用锁 推荐使用

  1. public sealed class Singleton
  2.  
  3. {
  4.  
  5. private static readonly Singleton instance = new Singleton();
  6.  
  7. // 显示的static 构造函数
  8.  
  9. //没必要标记类型 - 在field初始化以前
  10.  
  11. static Singleton()
  12.  
  13. {
  14.  
  15. }
  16.  
  17. private Singleton()
  18.  
  19. {
  20.  
  21. }
  22.  
  23. public static Singleton Instance
  24.  
  25. {
  26.  
  27. get
  28.  
  29. {
  30.  
  31. return instance;
  32.  
  33. }
  34.  
  35. }
  36.  
  37. }

欢迎关注我的公众号(同步更新文章)DoNet技术分享平台

阅读原文

C#开发模式——单例模式的更多相关文章

  1. 【python之路33】开发模式单例模式及简单的服务器请求框架原理

    1.单例模式指的是创建单个实例,例如:数据库连接池中包含10个数据库连接,用户访问数据时随机从连接池中拿出一个进行连接,其他用户再次访问时不再创建对象进行连接 #!usr/bin/env python ...

  2. Aoite 系列(04) - 强劲的 CommandModel 开发模式(上篇)

    Aoite 是一个适于任何 .Net Framework 4.0+ 项目的快速开发整体解决方案.Aoite.CommandModel 是一种开发模式,我把它成为"命令模型",这是一 ...

  3. js开发模式

    js中的开发模式进化史: js中有最初的只能由基本数据类型描述——>单例模式-->工厂模式-->构造函数模式-->原型模式-->各个模式相结合的混合模式,下面我会给大家逐 ...

  4. webpack+react+redux+es6开发模式

    一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...

  5. 企业应用开发模式 ERP项目中应用到的技术和工具

    一.基础技术选型 C# .NET 3.5/4.0  这两个版本的.NET已经相当方便(Linq, Lambda,Parallel),语法简洁,配合WCF和WF两项技术,可以满足快速开发,维护方便的目标 ...

  6. webpack+react+es6开发模式

    一.前言 实习了两个月,把在公司用到的前端开发模式做个简单的整理.公司里前端开发模式webpack+react+redux+es6,这里去掉了redux. webpack, react, redux等 ...

  7. 一种开发模式:ajax + ashx + UserControl

    一.ajax+ashx模式的缺点     在web开发过程中,为了提高网站的用户体验,或多或少都会用到ajax技术,甚至有的网站全部采用ajax来实现,大量使用ajax在增强用户体验的同时会带来一些负 ...

  8. ASP.NET MVC——CodeFirst开发模式

    Entity Framework框架提供了几种开发模式,比如Database First,Model First,Code First.Database First是最老也是应用得最广泛的一种设计方式 ...

  9. java 开发模式

    Java-开发模式 Java Web开发方案有多种,这里列举一些经典的开发模式进行横向比较JSP+JAVABEAN开发模式:    特点:该模式将业务逻辑与页面表现进行分离,在一定程度上增加了程序的可 ...

随机推荐

  1. 不用媒体查询做web响应式设计-遁地龙卷风

    (0)写在前面 讲述知乎上看到的一篇文章中的一个案例,让我脑洞大开,佩服至极,特意第二天找到原文赞赏了 5元,原文地址https://zhuanlan.zhihu.com/p/27258076,案例用 ...

  2. [BZOJ3675]序列分割

    3675: [Apio2014]序列分割 Time Limit: 40 Sec  Memory Limit: 128 MB Description 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H ...

  3. Linux上的防病毒软件ClamAV

    Clam AntiVirus(ClamAV)是免费而且开放源代码的防毒软件,软件与病毒码的更新皆由社群免费发布.目前ClamAV主要是使用在由Linux.FreeBSD等Unix-like系统架设的邮 ...

  4. Linux sort -g 的困惑

    sort命令是帮我们依据不同的数据类型进行排序,排序的效率很高,因此也是很常用的命令. sort参考及说明:https://www.gnu.org/software/coreutils/manual/ ...

  5. [0] DDD领域驱动设计(三) 之 聚合(根)、实体、值对象

    1.      聚合根.实体.值对象的区别? 从标识的角度: 聚合根具有全局的唯一标识,而实体只有在聚合内部有唯一的本地标识,值对象没有唯一标识,不存在这个值对象或那个值对象的说法: 从是否只读的角度 ...

  6. Webpack 3 中的新特性

    本文简短地分享下最新发布的 Webpack 3 中的新特性,供大家参考. 1. Webpack 3 的新特性 6 月 20 日,Webpack 发布了最新的 3.0 版本,并在 Medium 发布了公 ...

  7. jQuery – 鼠标经过(hover)事件的延时处理

    一.关于鼠标hover事件及延时 鼠标经过事件为web页面上非常常见的事件之一.简单的hover可以用CSS :hover伪类实现,复杂点的用js. 一般情况下,我们是不对鼠标hover事件进行延时处 ...

  8. Zabbix 3.2.6安装过程

    以3.2.6版本的Zabbix为例展开说明 1.准备Lnmp环境. 本次准备的环境: Linux:2.6.32-642.el6.x86_64 Nginx:1.12.0 Mariadb:10.2.6 P ...

  9. php5.6在yum下安装gd库

    yum install php-gd --enablerepo=remi,remi-php56 php.ini配置文件中增加 extension=gd.so 重启web服务器即可

  10. 团队开发冲刺2-----1day

    第二冲刺阶段团队软件开发第二阶段冲刺 冲刺目标: 1.在第一阶段的基础上完成app内部界面设计. 2.逐步完成app内每一部分内容. 3.对app的实现进一步仔细钻研考虑. 4.对app每一部分内容模 ...