版本一:

/// <summary>
/// A simple singleton class implements.
/// </summary>
public sealed class Singleton
{
    private static Singleton _instance = null;

/// <summary>
    /// Prevents a default instance of the
    /// <see cref="Singleton"/> class from being created.
    /// </summary>
    private Singleton()
    {
    }

/// <summary>
    /// Gets the instance.
    /// </summary>
    public static Singleton Instance
    {
        get { return _instance ?? (_instance = new Singleton()); }
    }
}

以上的实现方式适用于单线程环境,因为在多线程的环境下有可能得到Singleton类的多个实例。假如同时有两个线程去判断

(null == _singleton),并且得到的结果为真,那么两个线程都会创建类Singleton的实例,这样就违背了Singleton模式“唯一实例”的初衷。

版本二:

/// <summary>
/// A thread-safe singleton class.
/// </summary>
public sealed class Singleton
{
private static Singleton _instance = null;
private static readonly object SynObject = new object(); Singleton()
{
} /// <summary>
/// Gets the instance.
/// </summary>
public static Singleton Instance
{
get
{
// Syn operation.
lock (SynObject)
{
return _instance ?? (_instance = new Singleton());
}
}
}
}

以上方式的实现方式是线程安全的,首先我们创建了一个静态只读的进程辅助对象,由于lock是确保当一个线程位于代码的临界区时,另一个线程不能进入临界区(同步操作)。如果其他线程试图进入锁定的代码,则它将一直等待,直到该对象被释放。从而确保在多线程下不会创建多个对象实例了。只是这种实现方式要进行同步操作,这将是影响系统性能的瓶颈和增加了额外的开销。

版本三:

/// <summary>
/// Double-Checked Locking implements a thread-safe singleton class
/// </summary>
public sealed class Singleton
{
    private static Singleton _instance = null;
    // Creates an syn object.
    private static readonly object SynObject = new object();

Singleton()
    {
    }

public static Singleton Instance
    {
        get
        {
            // Double-Checked Locking
            if (null == _instance)
            {
                lock (SynObject)
                {
                    if (null == _instance)
                    {
                        _instance = new Singleton();
                    }
                }
            }
            return _instance;
        }
    }
}

版本四:经典模式

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;
        }
}

版本七:延迟初始化

/// <summary>
/// Delaies initialization.
/// </summary>
public sealed class Singleton
{
    private Singleton()
    {
    }

/// <summary>
    /// Gets the instance.
    /// </summary>
    public static Singleton Instance { get { return Nested._instance; } }

private class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

internal static readonly Singleton _instance = new Singleton();
    }
}

版本八:静态初始化

public sealed class Singleton
{
    private static readonly Singleton _instance = new Singleton();

// Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

/// <summary>
    /// Prevents a default instance of the
    /// <see cref="Singleton"/> class from being created.
    /// </summary>
    private Singleton()
    {
    }

/// <summary>
    /// Gets the instance.
    /// </summary>
    public static Singleton Instance
    {
        get
        {
            return _instance;
        }
    }
}

C#の单例模式的更多相关文章

  1. C++实现线程安全的单例模式

    在某些应用环境下面,一个类只允许有一个实例,这就是著名的单例模式.单例模式分为懒汉模式,跟饿汉模式两种. 首先给出饿汉模式的实现 template <class T> class sing ...

  2. 23种设计模式--单例模式-Singleton

    一.单例模式的介绍 单例模式简单说就是掌握系统的至高点,在程序中只实例化一次,这样就是单例模式,在系统比如说你是该系统的登录的第多少人,还有数据库的连接池等地方会使用,单例模式是最简单,最常用的模式之 ...

  3. angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用

    今天我们要讲的是ng2的路由系统. 例子

  4. java设计模式之--单例模式

    前言:最近看完<java多线程编程核心技术>一书后,对第六章的单例模式和多线程这章颇有兴趣,我知道我看完书还是记不住多少的,写篇博客记录自己所学的只是还是很有必要的,学习贵在坚持. 单例模 ...

  5. 设计模式C#合集--单例模式

    单例模式 代码: 第一种: private static Singleton singleton = null; private Singleton() { } public static Singl ...

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

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

  7. GOF23设计模式之单例模式

    ·核心作用: -保证一个类只有一个实例,并且提供一个访问该实例的全局访问点. ·常见应用场景: -Windows的Task Manager(任务管理器)就是很典型的单例模式 -Windows的Recy ...

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

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

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

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

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

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

随机推荐

  1. vue-组件之间的通信:

    组件之间的通信:一个组件被调用,那么里面的数据就需要从前者调用,因为在开发中组件时重复调用的,在页面中会反复使用,但是里面的数据是不一样的,谁调用这个组件谁就传递数据给这个组件,所以就要暴露一些接口, ...

  2. NOIp2018集训test-9-6(pm)

    T1T2是洛谷原题.Orz辉神290,被辉神吊起来打. 题 1 包裹快递 二分答案.这题似乎卡精度,不开long double二分500次都过不去. //Achen #include<algor ...

  3. shell得到两个文件的差集

    第一种方法: grep: [root@hdp05 src]# grep -vxFf leadering.txt leaderNum.txt [root@hdp05 src]# cat leaderin ...

  4. Git 学习(三)Git 创建版本库

    获取 Git 仓库 什么是 Git 仓库呢,仓库又名版本库,我们可以把他理解为一个文件夹.这个文件夹里的所有东西都需要被 Git 给管理起来,对立面每个文件的修改.编辑.删除都将被 Git 记录,以便 ...

  5. python爬虫_从零开始破解js加密(一)

    除了一些类似字体反爬之类的奇淫技巧,js加密应该是反爬相当常见的一部分了,这也是一个分水岭,我能解决基本js加密的才能算入阶. 最近正好遇到一个比较简单的js,跟大家分享一下迅雷网盘搜索_838888 ...

  6. 刚装完Linux就CPU占用率高

    top命令发现如下三个进程占据了前三的CPU使用率 wpa_supplicant NetworkManager rsyslogd google发现前两个进程与无线网络有关,我的电脑是笔记本,插的有线, ...

  7. 18-Ubuntu-文件和目录命令-创建文件和目录-touch和mkdir

    1.touch 创建文件或修改文件时间 (1)如果文件不存在,可以创建一个空白文件 例: 创建空白文件01.txt touch 01.txt (2)如果文件已经存在,可以修改文件的末次修改时间 例: ...

  8. kafka 入门

    李克华 云计算高级群: 292870151 195907286 交流:Hadoop.NoSQL.分布式.lucene.solr.nutch  kafka入门:简介.使用场景.设计原理.主要配置及集群搭 ...

  9. 03->OpenGL多边形,glut实现三角形条带和三角形扇

    图形学中基本图元是多边形,一般要求是凸多边形,三角形是最简单的凸多边形,在图形渲染中比一般多边形其绘制速度快.今天学习OpenGL绘制三角形条带和三角形扇基础.编程环境! 1. 三角形条带 指定顶点序 ...

  10. 一个好的mvc5+ef6的学习地址

    链接地址: MVC5 + EF6 入门完整教程  感谢这位博主的无私奉献 文章目录列表:http://www.cnblogs.com/miro/p/3777960.html#3673688