它的主要特点不是根据客户程序调用生成一个新的实例,而是控制某个类型的实例数量-唯一一个。(《设计模式-基于C#的工程化实现及扩展》,王翔)。也就是说,单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点。

第一种最简单,但没有考虑线程安全,在多线程时可能会出问题.

public class Singleton
{
private static Singleton instance; private Singleton()
{ } public static Singleton GetInstance()
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}

解析如下:

  1)首先,该Singleton的构造函数必须是私有的,以保证客户程序不会通过new()操作产生一个实例,达到实现单例的目的;

  2)因为静态变量的生命周期跟整个应用程序的生命周期是一样的,所以可以定义一个私有的静态全局变量instance来保存该类的唯一实例;

  3)必须提供一个全局函数访问获得该实例,并且在该函数提供控制实例数量的功能,即通过if语句判断instance是否已被实例化,如果没有则可以同new()创建一个实例;否则,直接向客户返回一个实例。

  在这种经典模式下,没有考虑线程并发获取实例问题,即可能出现两个线程同时获取instance实例,且此时其为null时,就会出现两个线程分别创建了instance,违反了单例规则。因此,需对上面代码修改。

第二种为多线程下的单例模式,考虑了线程安全

public class Singleton
{
private static Singleton instance;
private static object _lock=new object(); private Singleton()
{ } public static Singleton GetInstance()
{
if(instance==null)
{
lock(_lock)
{
if(instance==null)
{
instance=new Singleton();
}
}
}
return instance;
}
}

上述代码使用了双重锁方式较好地解决了多线程下的单例模式实现。先看内层的if语句块,使用这个语句块时,先进行加锁操作,保证只有一个线程可以访问该语句块,进而保证只创建了一个实例。再看外层的if语句块,这使得每个线程欲获取实例时不必每次都得加锁,因为只有实例为空时(即需要创建一个实例),才需加锁创建,若果已存在一个实例,就直接返回该实例,节省了性能开销。

第三种饿汉模式

这种模式的特点是自己主动实例。

public sealed class Singleton
{
private static readonly Singleton instance=new Singleton(); private Singleton()
{
} public static Singleton GetInstance()
{
return instance;
}
}

上面使用的readonly关键可以跟static一起使用,用于指定该常量是类别级的,它的初始化交由静态构造函数实现,并可以在运行时编译。在这种模式下,无需自己解决线程安全性问题,CLR会给我们解决。由此可以看到这个类被加载时,会自动实例化这个类,而不用在第一次调用GetInstance()后才实例化出唯一的单例对象。

C#单例模式的多种写法的更多相关文章

  1. asp.net 连接字符串的多种写法

    一.使用OleDbConnection对象连接OLE DB数据源 1.连接Access 数据库 Access 2000: “provider=Microsoft.Jet.Oledb.3.5;Data ...

  2. JS实现单例模式的多种方案

    JS实现单例模式的多种方案 今天在复习设计模式中的-创建型模式,发现JS实现单例模式的方案有很多种,稍加总结了一下,列出了如下的6种方式与大家分享 大体上将内容分为了ES5(Function)与ES6 ...

  3. 单例模式,多种实现方式JAVA

    转载请注明出处:http://cantellow.iteye.com/blog/838473 第一种(懒汉,线程不安全): public class Singleton { private stati ...

  4. C#单例的多种写法

    单例的细分写法 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 最吊大的 一种--C#这样的高级语言特有 ...

  5. Objective-c单例模式的正确写法--用dispatch 线程安全

    单例模式在iOS开发中可能算是最常用的模式之一了,但是由于oc本身的语言特性,想要写一个正确的单例模式相对来说比较麻烦,这里我就抛砖引玉来聊一聊iOS中单例模式的设计思路.关于单例模式更多的介绍请参考 ...

  6. Python之单例模式的多种实现

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  7. Python if 和 for 的多种写法

    a, b, c = 1, 2, 3 [对比Cpp里:c = a >b? a:b]这个写法,Python只能常规的空行,缩进吗? 人生苦短,我用python,下面介绍几种if的方便的方法. 1.常 ...

  8. TSQL order by 子句中排序列的多种写法

    Order by 子句用于对结果进行排序,执行顺序位于select子句之后,排序列有4中写法: column_name column_alias,由于order by子句的执行顺序位于select子句 ...

  9. thinkphp的条件的多种写法

    class SelectAction extends Action{   function index(){ //thinkphp 查询语言  //         1.普通查询 //   2.区间查 ...

随机推荐

  1. java学习笔记之正则表达式

    一般来说,正则表达式就是以某种方式来描述字符串,因此你可与说:"如果一个字符串符合有这些东西,那么它就是我正在找的东西. 1.要找一个数字,如果它可能有一个负号在最前面(可能没有,没有也是匹 ...

  2. h5手机端下拉选择城市

    <!doctype html><html>    <head>            <meta http-equiv="Content-Type& ...

  3. 架构师养成记--11.Executor概述

    常用方法 Executors.newFiexdPool(int nThreads);固定线程数量的线程池: Executors.newSingleThreadExecutor();单个线程的线程池: ...

  4. nodejs异步处理

    采用Async.Q.Promise等第三方库处理异步回调 Async 安装 npm install async --save-dev

  5. Python MongoDB使用介绍

    MongoDB介绍 MongoDB是一个面向文档的,开源数据库程序,它平台无关.MongoDB像其他一些NoSQL数据库(但不是全部!)使用JSON结构的文档存储数据.这是使得数据非常灵活,不需要的S ...

  6. 你想要了解但是却羞于发问的有关SSL的一切

    Everything You Ever Wanted to Know About SSL (but Were Afraid to Ask) Or perhaps more accurately, &q ...

  7. 关于win7 安装redis的问题

    首先在https://github.com/MSOpenTech/redis/releases下载64位的安装包 到任意盘中 将改名为redis 使用cmd命令 启动redis 进入 redis 目录 ...

  8. 利用vim查看日志,快速定位问题

    起因 在一般的情况下,如果开发过程中测试报告了一个问题,我一般会这么做: 1.在自己的开发环境下重试一下测试的操作,看看能不能重现问题.不行转2 2.数据库连接池改成测试库的地址,在自己的开发环境下重 ...

  9. thinkphp疑难解决4

    关于文件上传所涉及到的php.ini 中的一些配置: (以当前要设置的关键字开头...) 是每个上传文件所允许的大小, 默认的 upload_max_filesize = 2M, 如果超过了2M,_P ...

  10. ActiveMQ中的Destination高级特性(一)

    ---------------------------------------------------------------------------------------- Destination ...