• 单例模式完整解析


    volatile, static readonly, double check

    直到对象要求产生一个实例才执行实例化;这种方法称为"懒实例化"。懒实例化避免了在应用程序启动时实例化不必要的 singleton

    1. 

    using System; 
    public class Singleton 
    { 
       private static Singleton instance; 
       private Singleton() {} 
       public static Singleton Instance 
       { 
          get  
          { 
             if (instance == null) 
             { 
                instance = new Singleton(); 
             } 
             return instance; 
          } 
       } 
    }

    但是,这种实现的主要缺点是在多线程环境下它是不安全的。如果执行过程的不同线程同时进入 Instance 属性方法,那么可能会创建多个 Singleton 对象实例。每个线程都会执行下列语句,并决定必须创建新的实例:

    if (instance == null) 

    解决此问题的方法有很多。一种方法是使用被称为 Double-Check Locking 的技术。而 C# 与公共语言运行库也提供了一种"静态初始化"方法,这种方法不需要开发人员显式地编写线程安全代码,即可解决这些问题。

    2.  C# 与公共语言运行库提供的"静态初始化"方法

    One of the reasons Design Patterns 避免使用静态初始化的原因之一是,C++ 规范在静态变量的初始化顺序方面留下了一些多义性。幸运的是,.NET Framework 通过其变量初始化处理方法解决了这种多义性:

    public sealed class Singleton 
    { 
       private static readonly Singleton instance = new Singleton(); 
       private Singleton(){} 
       public static Singleton Instance 
       { 
          get  
          { 
             return instance;  
          } 
       } 
    } 

    3. Double-Check Locking方法

    用volatile修饰instance, 只有实例变量instance分配完,其他线程才能访问它,多线程读它的时候要么是null,要么是完整的分配好的对象。

    lock的对象是private的object对象,不要lock公有的对象比如this,type,以免发生死锁。

    using System; 
    public sealed class Singleton 
    { 
       private static volatile Singleton instance; 
       private static object syncRoot = new Object(); 
       private Singleton() {} 
       public static Singleton Instance 
       { 
          get  
          { 
             if (instance == null)  
             { 
                lock (syncRoot)  
                { 
                   if (instance == null)  
                      instance = new Singleton(); 
                } 
             } 
             return instance; 
          } 
       } 
    }

    此 double-check locking 方法解决了线程并发问题,同时避免在每个 Instance 属性方法的调用中都出现独占锁定。这里的避免独占锁定是不需要锁定整个Instance属性方法,性能不受影响。它还允许您将实例化延迟到第一次访问对象时发生。实际上,应用程序很少需要这种类型的实现。大多数情况下,静态初始化方法已经够用。

    优点:Double-Check Locking 技术已在公共语言运行库中正确实现。但是其他环境中还是会有一些常见的、与使用 Double-Check Locking 有关的问题。

    总结:

    最后还是推荐用"静态初始化"方法实现Singleton。实现简单,实现依赖于CLR框架解决多线程问题。

    参考文章:

    http://msdn.microsoft.com/zh-cn/library/ff650316.aspx

    http://msdn.microsoft.com/zh-cn/library/ms954629.aspx

    http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

  • 相关阅读:
    WIN8开启AHCI的方法终于得到解决。
    Androidx86入门之让你的Androidx86竖屏起来
    Android软件去广告教程
    opencv 3 core组件进阶(2 ROI区域图像叠加&图像混合;分离颜色通道、多通道图像混合;图像对比度,亮度值调整)
    opencv 4 图像处理 (1 线性滤波,非线性滤波)
    opencv 3 core组件进阶(3 离散傅里叶变换;输入输出XML和YAML文件)
    php正则指定字符串内容preg_match函数之说明
    dedecms pagelist标签修改方法
    php后台多用户权限组思路与实现程序代码
    php中获取文件后缀名多种方法
  • 原文地址:https://www.cnblogs.com/dirichlet/p/3252547.html
Copyright © 2020-2023  润新知