《大话设计模式》--笔记(单例模式)

单例模式:保证一个类仅有一个实例,并提供一个供访问的全局点。
其它优点:单例模式因为是卦装的它的唯一实例,这样它可以严格地控制客户怎样访问它以及何时访问它。
简单的说就是对唯一实例的受控访问。

 

/// <summary> /// 定义一个GetInstance操作,允许客户访问他的唯一实例,GetInstance是一个静态方法 /// 主要负责创建自己的唯一实例 /// </summary> class Singleton { private static Singleton instance; /// <summary> /// 构造方法让其私有,这就表示外界不能使用new()来创建对象了 /// </summary> private Singleton() { } /// <summary> /// 获取本实例的唯一全局访问点 /// </summary> /// <returns></returns> public static Singleton GetInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }

 

 

调用:

 

class Program { static void Main(string[] args) { Singleton singleton0 = Singleton.GetInstance(); Singleton singleton1 = Singleton.GetInstance(); if (singleton0 == singleton1) { Console.WriteLine("两个对象是相同的实例"); } Console.Read(); } }  

 

以上方式存在不足。


在多线程的程序中,多个线程同时访问单例类,调用GetInstance()方法,会有可能造成创建多个实例
在这种情况下,给进行加一把锁来处理。(lock)

多线程时的单例

 

现对以上Singleton类进行改良

 

 

/// <summary> /// 线程中定义一个GetInstance操作,允许客户访问他的唯一实例,GetInstance是一个静态方法 /// 主要负责创建自己的唯一实例 /// </summary> class SynSingleton { private static SynSingleton synsingleton; private static readonly object synroot = new object(); //创建一个静态只读的进程辅助对象 /// <summary> /// 构造方法让其私有,这就表示外界不能使用new()来创建对象了 /// </summary> private SynSingleton() { } public static SynSingleton GetInstance() { lock (synroot) //要同一时刻被加锁后只能有一个线程进入 { if (synsingleton == null) { synsingleton = new SynSingleton(); } } return synsingleton; } }

 

 

lock是确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定代码,
则它将一直等,直到对象被释放。
SynSingleton类中使用的线程lock是能达到目的,但对性能有影响。
可以采用双重锁定来改良一下。

 

如下:

 

/// <summary> /// (采用双重锁定)线程中定义一个GetInstance操作,允许客户访问他的唯一实例,GetInstance是一个静态方法 /// 主要负责创建自己的唯一实例 class DoubleSynSingleton { private static DoubleSynSingleton doublesyninstance; private static readonly object doublesynroot = new object(); private DoubleSynSingleton() { } public static DoubleSynSingleton GetInstance() { if (doublesyninstance == null) { lock (doublesynroot) { if (doublesyninstance == null) { doublesyninstance = new DoubleSynSingleton(); } } } return doublesyninstance; } }  

 

注:
   实际应用当中,C#与公共语言运行库也提供了一种“静态初始化”方法,这种方法不需要开发人员显示的编写线程安全代码
   即可解诀多线程环境下它是不安全的问题
  例如:
  //关键字sealed 阻步派生,以免发生多个实例
   public sealed class Singleton   
   {
      private static readonly Singleton instance=new Singleton();  //在第一次引用类的任何成员时创建实例,公共语言库负责处理变量初始化
     
      private Singleton()
      {}
     
      public static Singleton GetInstance()
      {
         return instance;
      }
     
   }
   以上这种方式也被称为懒汉式单例模式

你可能感兴趣的:(设计模式,多线程,object,null,Class,语言)