C# 单例模式(复习用)

摘要:
它还为客户端提供了获取实例的全局访问点。为了确保客户端程序不会通过new()操作生成实例,可以定义一个私有静态全局变量实例来保存该类的唯一实例;3) 必须提供全局函数访问才能获取实例。尚未考虑线程并发获取实例的问题。也就是说,两个线程可以同时获得实例上面的代码使用双锁方法来更好地解决多线程下的单实例模式实现。
单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点。

  一、经典模式:

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,违反了单例规则。因此,需对上面代码修改。

  二、多线程下的单例模式

  1、Lazy模式

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语句块,这使得每个线程欲获取实例时不必每次都得加锁,因为只有实例为空时(即需要创建一个实例),才需加锁创建,若果已存在一个实例,就直接返回该实例,节省了性能开销。

  2、饿汉模式

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


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

        public static Singleton GetInstance()
        {
               return instance;
        }
}

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

免责声明:文章转载自《C# 单例模式(复习用)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇matlab绘图方法汇总ubuntu 安装mysql5.7下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

死锁检测

曾经参与过的一款网络游戏,其服务器使用了异常复杂的多线程序解决方案。导致应用层程序员编写的代码很容易就出现死锁。 最终,公司的一个老员工,只能开发了一个死锁检测框架,在debug模式下运行时,只要发生死锁就会打印出调用堆栈。 虽然说这个框架基本可以在上线前把所有的死锁都检测了出来,但是,规根到底这是设计不合理造成的,多线程利用好了会提升 应用的效率,用不好...

winform进程、线程

随笔- 86 文章- 0 评论- 0 winform进程、线程 进程: 一般来说,一个程序就是一个进程,不过也有一个程序需要多个进程支持的情况。 进程所使用的类:Process 所需命名空间:System.Diagnostics; 可以通过进行来开启计算机上现有的程序: 1、使用静态方法Start();但必须要知道进程名 2、也可以实例化对象,来调用S...

gnuplot运行方式

gnuplot运行方式 terminal terminal下输入gnuplot,进入command line interact 单行命令模式 gnuplot -p -e ‘command1;command2; plot function’ 脚本模式 gnuplot -p /path_to_script/script.p,扩展名为.p,opt...

并发编程-线程池(二)线程池回收线程

【1】https://blog.csdn.net/u013256816/article/details/109213183   面试 鹅厂 的时候,问到了 线程池如何销毁线程,这题答的不好。   这个问题考察的是对线程池的理解,在既然了解了线程池在什么时候创建线程。   那么也要了解线程池在不同情况是如何回收线程,什么时候回收,怎么回收。 一、线程池状态和...

Python-GIL 进程池 线程池

5、GIL vs 互斥锁(*****) 1、什么是GIL(Global Interpreter Lock) GIL是全局解释器锁,是加到解释器身上的,保护的就是解释器级别的数据 (比如垃圾回收的数据) 同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码 2 为什...

HTML5触屏版多线程渲染模板技术分享

  前言: 了解js编译原理的屌丝们都知道,js是单线程的,想当年各路神仙为了实现js的多线程,为了解决innerHTML输出大段HTML卡页面的顽疾,纷纷设计了诸如假冒的“多线程“实现,我自己也在写开源框架KitJs时候,写过类似的组件http://www.cnblogs.com/xueduanyang/archive/2012/05/30/252642...