单件模式(Singleton Pattern)

一、介绍

  单件模式要求一个类有且只有一个实例,并且提供一个全局访问点。

  例如:团购网上,商品库存问题,为了促进广告效益,常常会拿一些商品,比如说库存为10,以低价出售,然后竞拍的用户几乎是百万来计。但是商品库存是有限的。所以此时需要定义一个全局的访问点,且实例只有一个,每成功接收一个订单,库存减1。

二、实现

  I、简单实现

View Code
 //Singleton简单实现
   public sealed  class SimpleSingleton
    {
       static SimpleSingleton instance = null;
       private SimpleSingleton() { }
       public static SimpleSingleton Instance
       {
           get
           {
               if (instance==null) {
                   instance = new SimpleSingleton();
               }
               return instance;
           }
       }
    }

这种实现方法对线程来说并不是安全的,来我们的示例来说,用户是百万级的,存在两个线程中,同时判断instance==null为真的概率是非常大的,这时会同时创建两个实例,造成的结果:库存量错乱。本来只是拿10件商品来促销,但却接收到了11个订单。

  II、线程安全

View Code
//安全的线程
   public sealed class SecureSingleton
   {
       static SecureSingleton instance = null;
       static readonly object obj=new object();
       private SecureSingleton(){}
       public static SecureSingleton Instance {
           get {
               lock (obj)
               {
                   if (instance == null)
                   {
                       instance = new SecureSingleton();
                   }
                   return instance;
               }
           }
       }
   }

 

这种实现方法对线程是安全的,我们首先建立个辅助对象,第一个线程进入后,先对辅助对象加锁,后判断对象是否存在,不存在则创建.如第一个线程进来后,还未释放锁,此时第二个线程进来,会判断,辅助对象不是加了锁,如加了锁则等待释放。这样就不会实例化多个对象。不过此时性能有所损失。

  III、双重锁定(以前一直以为是双锁,其实是双重判断+锁定)

View Code
//双重锁定(以前一直以为是双锁,其实是双重判断+锁定)
   public sealed class DoubleSingleton
   {
       static DoubleSingleton instance = null;
       static readonly object obj = new object();
       private DoubleSingleton() { }
       public static DoubleSingleton Instance
       {
           get {
               if (instance == null)
               {
                   lock (obj)
                   {
                       if (instance == null)
                       {
                           instance = new DoubleSingleton();
                       }
                   }
               }
               return instance;
           }
       }
   }

 对于线程是安全的,同时又不用每次判断辅助对象是否加了锁,提高了性能。

  IV、静态初始化

View Code
 //静态初始化
   public sealed class StaticSingleton
   {
       static StaticSingleton instance = null;
       private StaticSingleton() { }
       public static StaticSingleton Instance 
       {
           get {
               return instance;
           }
       }
   }

 编译时发生,.net 中单件的首选方法。缺点:实例化机制的控制权较少

  V、延迟初始化

View Code
  //延迟初始化
   public sealed class DelaySingleton
   {
       public static DelaySingleton Instance
       {
           get { return Intance.instance; }
       }
   }
    //延迟对象
   class Intance {
       static Intance() { }
       public static readonly DelaySingleton instance = new DelaySingleton();
   }

 弥补了静态初始化的缺点

posted @ 2012-05-09 13:56  ヾJ﹍Hヾ  阅读(419)  评论(0编辑  收藏  举报