简体   繁体   English

C#中的单例线程安全 - 为什么要添加双重检查?

[英]Singleton thread safe in C# - why to add the double check?

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;
      }
   }
}

I don't understand why is the double check ! 我不明白为什么要仔细检查! I read that this double check is to solve the thread concurrency problems - but ... 我读到这个双重检查是为了解决线程并发问题 - 但是......

  1. The lock will solve it - so why we need to first 'if' 锁将解决它 - 所以我们需要先'如果'

  2. if this singleton will be without the first 'if' it still will be thread safe - right ? 如果这个单例将没有第一个'if',它仍然是线程安全的 - 对吗?

  3. if the first 'if' is false - so thread1 will init the 'instance' object => now, the 'instance' is not null and the thread1 is still in the lock block ===>> now, thread2 check the first 'if' and will get false => so he will not get to the 'lock' and imminently will return the instance and thread2 is able to change properties of the 'instance' => so thread1 && thread2 are 'working' on same 'instance' object => so where is the thread safe ... or what I'm missing here. 如果第一个'if'为false - 那么thread1将初始化'instance'object => now,'instance'不为null且thread1仍然在锁定块中=== >> now,thread2检查第一个' if'并且会得到false =>所以他不会进入'lock'并且迫切地将返回实例并且thread2能够更改'instance'=>的属性,因此thread1 && thread2在同一'实例上'工作' 'object =>所以线程安全在哪里......或者我在这里缺少什么。

1.The lock will solve it - so why we need to first 'if' 1.锁将解决它 - 所以我们需要先'如果'

So you won't lock the thred unless you need to create the new instance of the Singleton. 因此,除非您需要创建Singleton的新实例,否则不会锁定thred。
lock is a very expensive operation , so it's worth doing that extra check. lock是一个非常昂贵的操作 ,所以值得做额外的检查。

2.if this singleton will be without the first 'if' it still will be thread safe - right ? 2.如果这个单例将没有第一个'if',它仍然是线程安全的 - 对吗?

Yes, but significantly slower. 是的,但速度要慢得多。

3.Thread1 && thread2 are 'working' on same 'instance' object => so where is the thread safe 3.Thread1 && thread2在'instance'object =>上'工作',所以线程安全在哪里

This is the whole point of singleton, only one instance for all threads. 这是单例的全部要点,所有线程只有一个实例。 That's the thread safe thing... 那是线程安全的事情......

I assume that if ThreadA gets interrupted just before the lock ; 我假设如果ThreadA在lock之前被中断; ThreadB successfully completes the creation of the singleton then when ThreadA resumes it'll try to recreate the singleton once the lock is released. ThreadB成功完成单例的创建,然后当ThreadA恢复时,一旦释放锁,它将尝试重新创建单例。

the if checks if the singleton is already instantiated if not it create a new instace. if检查单例是否已经实例化,如果没有它创建一个新的实例。 and the lock ensure threadsafety. 锁定确保线程安全。

without the if it would create a new instace on every call (not the idea of singleton). 如果它会在每次调用时创建一个新的实例(不是单例的想法)。 without the lock it would be able that two threads could simulatanusly create a instance, so it would be possible that two instances exists. 如果没有锁定,两个线程就可以同时创建一个实例,因此可能存在两个实例。

if you are only using single threading you can wipe the lock. 如果您只使用单线程,则可以擦除锁定。 otherwise (on mt) it's highly recommended to use it. 否则(在mt上)强烈建议使用它。

Here is a good paper from the University of Maryland on why it is recommended (and why it does not always work in modern optimizing compilers) This is a good read if you have time. 以下是马里兰大学关于为何推荐它的好文章(以及为什么它并不总是适用于现代优化编译器)如果你有时间,这是一个很好的阅读。

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

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

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