• 单件模式(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();
       }

     弥补了静态初始化的缺点

  • 相关阅读:
    drf-通过drf-extensions扩展来实现缓存
    social_django第三方登录 没有token解决方法
    python-项目日志配置使用
    drf-支付宝支付
    git 相关命令
    django第三方登录与邮箱验证流程
    django项目部署
    数组中的方法
    滚动到页面底部,更新数据
    图片卷边
  • 原文地址:https://www.cnblogs.com/duandian/p/2491649.html
Copyright © 2020-2023  润新知