c#项目中实现单例模式的方法有哪些

  

c#项目中实现单例模式的方法有哪些?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

介绍

单例模式是软件工程学中最富盛名的设计模式之一。从本质上看,单例模式只允许被其自身实例化一次,且向外部提供了一个访问该实例的接口。通常来说,单例对象进行实例化时一般不带参数,因为如果不同的实例化请求传递的参数不同的话会导致问题的产生。(若多个请求都是传递的同样的参数的话,工厂模式更应该被考虑)

c#中实现单例有很多种方法,本文将按顺序介绍非线程安全,完全懒汉式、线程安全和低/高性能集中版本。

在所有的实现版本中,都有以下几个共同点:

<李>

唯一的,私有的且无参的构造函数,这样不允许外部类进行实例化;

<李>

类是密封的,尽管这不是强制的,但是严格来讲从上一点来看密封类能有助于JIT的优化;

<李>

一个静态变量应该指向类的唯一实例;

<李>

一个公共的静态变量用于获得这个类的唯一实例(如果需要,应该创建它),

需要注意的是,本文中所有的例子中都是用一个公共静态实例的变量来访问单例类实例,要将其转换成公共函数是很容易的,但是这样并不会带来效率和线程安全上的提升。

版本1 -非线程安全

///, & lt; summary>///,Bad 代码! Do  not 使用!,///,& lt;/summary>   public  sealed  class 单例   {   ,private  static  Singleton  instance =,空;   ,private 单例(),{,}   ,public  static  Singleton 实例   ,{   ,得到   {才能   ,,if  (instance ==, null)   ,,{   ,,,instance =, new 单例();   ,,}   ,,return 实例;   ,,}   ,}   }

该版本在多线程下是不安全的,会创建多个实例,请不要在生产环境中使用!

因为如果两个线程同时运行到如果(实例==null)判断时,就会创建两个实例,这是违背单例模式的初衷的。实际上在后面那个线程进行判断是已经生成了一个实例,但是对于不同的线程来说除非进行了线程间的通信,否则它是不知道的。

版本2 -简单的线程安全

public  sealed  class  Singleton2   {   ,private  static  Singleton2  instance =,空;   ,private  static  readonly  object  obj =, new 对象();   ,private  Singleton2 (), {,}   public  Singleton2 实例   ,{   ,得到   {才能   ,,lock  (obj)   ,,{   ,,,if  (instance ==, null)   ,,,{   ,,,,instance =, new  Singleton2 ();   ,,,}   ,,,return 实例;   ,,}   ,,}   ,}   }

该版本是线程安全的。通过对一个过线程共享的对象进行加锁操作,保证了在同一时刻只有一个线程在执行锁{}里的代码。当第一个线程在进行实例判断或创建时,后续线程必须等待直到前一线程执行完毕,因此保证了只有第一个线程能够创建实例实例。

但不幸的是,因为每次对实例的请求都会进行锁操作,其性能是不佳的。

需要注意的是,这里使用了一个私有静态对象变量进行锁定,这是因为当如果对一个外部类可以访问的对象进行锁定时会导致性能低下甚至死锁,因此通常来说为了保证线程安全,进行加锁的对象应该是私人的。

版本3 -仔细检查锁紧的线程安全

///, & lt; summary>///,Bad  code  !, Do  not 使用!///,& lt;/summary>   public  sealed  class  Singleton3   {   ,private  static  Singleton3  instance =,空;   ,private  static  object  obj =, new 对象();   ,private  Singleton3 (), {,}   ,public  static  Singleton3 实例   ,{   ,得到   {才能   ,,if  (instance ==, null)   ,,{   ,,,lock  (obj)   ,,,{   ,,,,if  (instance ==, null)   ,,,,{   ,,,,,instance =, new  Singleton3 ();   ,,,,}   ,,,}   ,,}   ,,return 实例;   ,,}   ,}   }

该版本中试图去避免每次访问都进行加锁操作并实现线程安全。然后,这段代码对Java不起作用,因Java的内存模型不能保证在构造函数一定在其他对象引之用实例前完成。还有重要的一点,它不如后面的实现方式。

c#项目中实现单例模式的方法有哪些