单例模式学习笔记

单例模式的一个官方定义:确保一个类只有一个实例,并提供一个全局访问点。

根据单例模式的概念和上面的类图,总结了单例模式的以下三个要点:

<!–[if !supportLists]–>1. <!–[endif]–>定义私有的构造函数。一旦定义了私有的构造函数,在外界就不能通过new来创建它的实例了。因此能确保一个类只有一个实例。

<!–[if !supportLists]–>2. <!–[endif]–>要创建实例,就要有一个变量来保存该实例。因此需要定义静态私有变量来记录该类的唯一实例。

<!–[if !supportLists]–>3. <!–[endif]–>定义一个公有方法或者属性来把该类的实例公开出去。也就是需要提供类的全局访问点。

若考虑线程并发问题,当出现两个或更多的线程同时获取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语句块的加锁操作保证了只有一个线程可以访问该语句块,即只创建一个实例。外层if语句块先判断instance实例是否为空,这样每个线程不用每次都加锁,只有实例为空才加锁并创建实例。如果已经存在instance实例,就直接返回该实例,提高了程序的性能。