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

     弥补了静态初始化的缺点

  • 相关阅读:
    【刷题】LOJ 6009 「网络流 24 题」软件补丁
    lab 项目
    js内的时间戳指的是当前时间到1970年1月1日00:00:00 UTC对应的毫秒数,和 unix时间戳是对应的秒数,差了1000倍
    js 原生: 身份证脱敏、唯一随机字符串uuid、对于高 index 元素的隐藏与显示
    diy 滚动条 样式 ---- 核心代码
    PC_后台管理系统
    三端兼容项目
    阿里小程序
    到位App_jQuery_art-template
    一步一步 copy163: 网易严选 ---- vue-cli
  • 原文地址:https://www.cnblogs.com/duandian/p/2491649.html
Copyright © 2020-2023  润新知