zoukankan      html  css  js  c++  java
  • 单例模式完整解析

    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

  • 相关阅读:
    别让代码执行不必要的路径和让数据绑定执行了多次
    使用Excel学习英语单词
    如何通过访问记录改善网站质量
    Vs.net2005强势功能:数据源
    新产品:英语单词查找返回表格式结果
    为什么Cpu不能以100%运行 [不完全版]
    乐透彩票研究分析系统
    集成电路发明者杰克·基尔比 IC Inventor Jack Kilby
    ZigBee技术及其应用
    Unix传奇(上篇)
  • 原文地址:https://www.cnblogs.com/dirichlet/p/3252547.html
Copyright © 2011-2022 走看看