简体   繁体   English

Singleton设计模式与双重检查锁

[英]Singleton design pattern with double-check lock

Consider you have the following code: 考虑您有以下代码:
1. Why do we use double check lock, why single lock is not good enough, please provide detailed example. 1.为什么我们使用双重检查锁,为什么单锁不够好,请提供详细的例子。
2. What are the main drawbacks with this implementation? 2.这种实施的主要缺点是什么? and how should I prove it? 我该如何证明呢?
Thanks. 谢谢。

 public sealed class SomeSingleton5  
{  
    private static SomeSingleton5 s_Instance = null;
    private static object s_LockObj = new Object();

    private SomeSingleton5() { }

    public static SomeSingleton5 Instance
    {
        get
        {
            if (s_Instance == null)
            {
                lock (s_LockObj)
                {
                    if (s_Instance == null)
                    {
                        s_Instance = new SomeSingleton5();
                    }
                }
            }

            return s_Instance;
        }
    }
}

I think the best implementation of singleton class is provided by Jon Skeet . 我认为单身类的最佳实现是由Jon Skeet提供的。

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

Singleton by Jon Skeet Clarification 单身人士由Jon Skeet澄清

  1. Aquiring a lock is expensive. 获取锁是昂贵的。 Without the first if(s_Instance == null) check, a lock would be aquired each time someone accesses the singleton. 如果没有第一个if(s_Instance == null)检查, 每次有人访问单例时都会获取一个锁。 But a lock actually only needs to be there during instance creation . 但实际上只需要在实例创建过程中锁定。 So the first if(s_Instance == null) prevents the unnecessary locking. 所以第一个if(s_Instance == null)可以防止不必要的锁定。 The second if(s_Instance == null) needs to be there because initially two threads might have evaluated the first if(s_Instance == null) as true and the two threads would thereafter instanciate s_Instance after each other inside the lock. 第二个if(s_Instance == null)需要存在,因为最初两个线程可能已经将第一个if(s_Instance == null)评估为true ,然后两个线程将在锁内部彼此之后实例化s_Instance
  2. I don't see any real drawbacks in your implementation but with the alternative (static constructor, see below) we have a solution that is simpler and involves less code. 我没有看到你的实现有任何真正的缺点,但是使用替代方法(静态构造函数,见下文),我们有一个更简单且涉及更少代码的解决方案。 So it is more maintainable and less errorprone. 因此它更易于维护且错误更少。 Also it doesn't require locking at all. 它也根本不需要锁定。 As mentioned earlier, locking is expensive. 如前所述,锁定很昂贵。

you can improve it by using a static constructor: 你可以通过使用静态构造函数来改进它:

public sealed class SomeSingleton5  
{  
    // the compiler will generate a static constructor containing the following code 
    // and the CLR will call it (once) before SomeSingleton5 is first acccessed
    private static SomeSingleton5 s_Instance = new SomeSingleton5();

    private SomeSingleton5() { }

    public static SomeSingleton5 Instance
    {
        get
        {
            return s_Instance;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM