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

构成:

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. Sprint第三个冲刺(第六天)

    一.Sprint介绍 任务进度: 二.Sprint周期 看板: 燃尽图:

  2. C#方法的重载和方法的可变参数

    方法的重载 1.方法重载的前提:方法名称必须一样 2.构成重载的条件:参数不一样(参数数量不一样,参数类型不一样) 方法的可变参数 1.可变参数的值的数量可以是0到多个. 2.可变参数调用的时候,没有 ...

  3. 后缀数组 - 求最长回文子串 + 模板题 --- ural 1297

    1297. Palindrome Time Limit: 1.0 secondMemory Limit: 16 MB The “U.S. Robots” HQ has just received a ...

  4. C#中this的 四种 用法

    C#中的this用法,相信大家应该有用过,但你用过几种?以下是个人总结的this几种用法,欢迎大家拍砖,废话少说,直接列出用法及相关代码. this用法1:限定被相似的名称隐藏的成员 /// < ...

  5. 用Perl编写Apache模块续二 - SVN动态鉴权实现SVNAuth 禅道版

    代码地址:https://code.csdn.net/x3dcn/svnauth 以禅道项目管理系统的数据库结构为标准,实现了可用的svn authz验证功能. 以用户名.密码.项目的acl开发程度o ...

  6. coffeescript 1.8.0 documents

    CoffeeScript is a little language that compiles into JavaScript. Underneath that awkward Java-esque ...

  7. 序列中找子序列的dp

    题目网址: http://codeforces.com/problemset/problem/414/B Description Mashmokh's boss, Bimokh, didn't lik ...

  8. [.NET] SQL数据分页查询

    [.NET] SQL数据分页查询 程序下载 范例下载:点此下载 原始码下载:点此下载 NuGet封装:点此下载 数据查询 开发系统时,使用C#执行SQL查询指令,就可以从SQL数据库里查询所需数据. ...

  9. js argument实参集合与局部变量、参数关系

    形参 形式上传递的参数 function fn1(a,b,c) {//a,b,c就是形参 实参 实际传递的参数 fn1 (1,2,5);//1,2,5就是实参 argument 定义: 实参的集合 用 ...

  10. ng-click

    使用ng-clcik代码是发现其内的a标签失效: 于是测试下,发现绑定在document上的click事件在点击ng-click绑定的元素上也会失效: <div ng-click="c ...