单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

构成:

1.私有的构造函数

2.私有静态的实例

3.返回实例的静态方法

  public class Singleton
{
private static Singleton uniqueInstance = new Singleton();
private Singleton() { Console.WriteLine("this is a new singleton"); }
public static Singleton getInstance()
{
if (uniqueInstance == null)
{
return uniqueInstance;
}
return uniqueInstance;
}
}

这种叫做饿汉模式,实例在类加载时就创建了,缺点是如果实例如果消耗大量的资源而没有使用就会造成浪费,另一种懒汉模式,实例在被使用时才创建,

  public class Singleton
{
private static Singleton uniqueInstance;
private Singleton() { Console.WriteLine("this is a new singleton"); }
public static Singleton getInstance()
{
if (uniqueInstance == null)
{
return uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}

但是这不是线程安全的

例如

class Program {

        static void Main(string[] args) {
while (true) {
Thread t1 = new Thread(Test);
t1.Start();
}
}
static void Test() {
Singleton s = Singleton.getInstance();
} }

执行的结果有可能是这样

程序创建了多个实例,这不是我们想要的结果,原因是某个线程if (uniqueInstance == null)语句执行后让出了使用权,当它重新获得CPU使用权的时候,可能别的CPU已经创建了实例,而它并不知道,继续执行return uniqueInstance= new Singleton();导致出现多个实例。

因此,要为方法加锁

  public class Singleton
{
private static Singleton uniqueInstance;
private Singleton() { Console.WriteLine("this is a new singleton"); }
private static readonly object syncRoot = new object();
public static Singleton getInstance()
{
lock (syncRoot)
{
if (uniqueInstance == null)
{
  return uniqueInstance = new Singleton();
}
} return uniqueInstance;
}
}

但是这又带来了一个问题,在实例已经创建完成了,但还是会有大量的线程卡在lock (syncRoot),它们都还会尝试创建实例,这降低了性能

为此,还要为此方法创建另外一个验证

 public static Singleton getInstance()
{
if (uniqueInstance == null)
{
lock (syncRoot)
{
if (uniqueInstance == null)
{
  return uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}

此时,当实例已经创建完成之后,各线程不再访问临界区,提高了性能

单例模式和静态类的比较

1.单例模式可以懒加载,静态类执行更快(为什么?),即在不同条件下二者有不同的性能表现

2.单例可以继承和override

3.单例易于模拟,利于测试

4.单例利于维护状态信息

update:

1.静态类执行更快?

因为静态类在编译时绑定(什么是编译时绑定?)

2.stackoverflow上的回答

Vadluri Sreenu

  1. Singleton object stores in Heap but, static object stores in stack
  2. We can clone the object of Singleton but, we can not clone the static class object
  3. Singleton class follow the OOP(object oriented principles) but not static class
  4. we can implement interface with Singleton class but not with Static class.

Jon Skeet

A singleton allows access to a single created instance - that instance (or rather, a reference to that instance) can be passed as a parameter to other methods, and treated as a normal object.

A static class allows only static methods.

设计模式C#实现(六)——单例模式的更多相关文章

  1. Java并发程序设计(八)设计模式与并发之单例模式

    设计模式与并发之单例模式 简单的单例实现: public class Singleton { private Singleton(){ System.out.println("Creatin ...

  2. Java 设计模式系列(六)适配器模式

    Java 设计模式系列(六)适配器模式 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 适配器模式的结构: 类的适配器模式 对象 ...

  3. 设计模式(一)单例模式:创建模式 ASPNET CORE WEB 应用程序的启动 当项目中 没有STARTUP.CS 类如何设置启动 配置等等

    设计模式(一)单例模式:创建模式 先聊一下关于设计的几个原则(1)单一原则(SRP):一个类应该仅有一个引起它变化的原因 :意思就是 (一个类,最好只负责一件事情,并且只有一个引起它变化的原因(2)开 ...

  4. 设计模式(一)单例模式(Singleton Pattern)

    一.引言 最近在设计模式的一些内容,主要的参考书籍是<Head First 设计模式>,同时在学习过程中也查看了很多博客园中关于设计模式的一些文章的,在这里记录下我的一些学习笔记,一是为了 ...

  5. JAVA设计模式(6:单例模式详解)

    单例模式作为一种创建型模式,在日常开发中用处极广,我们先来看一一段代码: // 构造函数 protected Calendar(TimeZone var1, Locale var2) { this.l ...

  6. PHP设计模式(四)单例模式(Singleton For PHP)

    今天讲单例设计模式,这种设计模式和工厂模式一样,用的非常非常多,同时单例模式比较容易的一种设计模式. 一.什么是单例设计模式 单例模式,也叫单子模式,是一种常用的软件设计模式.在应用这个模式时,单例对 ...

  7. .NET设计模式(1):1.1 单例模式(Singleton Pattern)

    概述 单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点. 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单 ...

  8. java设计模式(四)--单例模式

    Singleton最熟悉不过了,下面学习单例模式.转载:http://zz563143188.iteye.com/blog/1847029 单例对象(Singleton)是一种常用的设计模式.在Jav ...

  9. Java设计模式学习笔记(单例模式)

    最近一直在看<Head First设计模式>,这本书写的确实是很不错的,专注于怎么用最简单的方式最通俗的语言让人了解设计模式.据说GoF的设计模式那本书写的很好,是一本经典,但是就是难懂, ...

随机推荐

  1. 如何花样展示自己的摄影作品?CSS+JS+Html

    注意:Windows平台推荐使用Edge.Chrome.FireFox,部分浏览器打不开 P.S.慢慢用鼠标在图片上拖拽会感觉更神奇     // 0.5 ? 1 : -1; }, ease: fun ...

  2. MySQL如何查询两个日期之间的记录

    baidu出来的结果多是下面答案:<quote> MySQL中,如何查询两个日期之间的记录,日期所在字段的类型为datetime(0000-00-00 00:00:00) 解决方案: 直接 ...

  3. 2013 - Lost connection to MySQL server at 'reading initial communication packet' 错误解决

    一.操作与状态 当使用MySQL客户端连接localhost本地数据库时,连接不上,报错.(使用Tomcat连接数据库时可以连接上,但需要很长的请求时间.) 二.原因与解决办法 关于这个问题网上的解决 ...

  4. P6 EPPM R16.1安装与配置指南(二)

    P6 EPPM R16.1安装与配置指南(一) http://www.cnblogs.com/endv/p/5634620.html P6 EPPM R16.1安装与配置指南(二) 环境变量配置 新建 ...

  5. 环信SDK与Apple Watch的结合(1)

    该系列是记录在apple watch上开发IM,用到了最近挺流行的环信IM SDK. 一.先来一段网上随处可查到的信息: 1.两种分辨率 1.65寸 312*390 1.5寸 272*340 2.开发 ...

  6. HTML5表单元素的学习

    本文内容              认识表单              基本元素的使用              表单高级元素的使用              现学现卖--创建用户反馈表单 ★  认识 ...

  7. C#中override和new修饰符的区别

    (new)“隐藏”,(override)“覆盖”(重写).不过要弄清楚这两个有什么区别确实也很难,因为子类在使用父类方法时根本看不出区别,子类不管父类是new了还是override了,用的都是父类方法 ...

  8. winform(MDI窗体容器、权限设置)

    一.MDI窗体容器: 1.功能: 它可以让其它窗体在它的内部打开,无法超出它的范围 将某个窗体的属性:IsMdiContainer设置为true - 窗口样式 2.问题: (1)如何将其它窗体在它的内 ...

  9. JavaScript基础12——js的方法重载

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  10. Tomcat一些小事

    1.编码问题 1.1.乱码 客户端发请GET请求,如果这个请求地址上有中文,而且也没有进行encode的时候,后端就可能接收到乱码. --解决办法 在tomcat , conf/server.xml ...