线程安全 C# 单例模式 [英] Thread Safe C# Singleton Pattern

查看:27
本文介绍了线程安全 C# 单例模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对此处记录的单例模式有一些疑问:http://msdn.microsoft.com/en-us/library/ff650316.aspx

I have some questions regarding the the singleton pattern as documented here: http://msdn.microsoft.com/en-us/library/ff650316.aspx

以下代码摘自文章:

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

具体来说,在上面的例子中,是否需要在锁定之前和之后将instance与null进行两次比较?这是必要的吗?为什么不先执行锁定再进行比较?

Specifically, in the above example, is there a need to compare instance to null twice, before and after the lock? Is this necessary? Why not perform the lock first and make the comparison?

简化为以下有问题吗?

   public static Singleton Instance
   {
      get 
      {
        lock (syncRoot) 
        {
           if (instance == null) 
              instance = new Singleton();
        }

         return instance;
      }
   }

执行锁定是否昂贵?

推荐答案

与简单的指针检查 instance != null 相比,执行锁定的成本非常.

Performing the lock is terribly expensive when compared to the simple pointer check instance != null.

您在此处看到的模式称为双重检查锁定.它的目的是避免只需要一次的昂贵的锁操作(当第一次访问单例时).之所以如此,是因为它还必须确保在初始化单例时不会出现线程竞争条件导致的错误.

The pattern you see here is called double-checked locking. Its purpose is to avoid the expensive lock operation which is only going to be needed once (when the singleton is first accessed). The implementation is such because it also has to ensure that when the singleton is initialized there will be no bugs resulting from thread race conditions.

这样想:只有当答案是是的,对象已经构建".但是如果答案是尚未构建",那么您没有足够的信息,因为您真正想知道的是尚未构建并且没有其他线程打算很快构建它".因此,您将外部检查用作非常快速的初始测试,并且仅当答案为否"时才启动正确、无错误但昂贵"的过程(锁定然后检查).

Think of it this way: a bare null check (without a lock) is guaranteed to give you a correct usable answer only when that answer is "yes, the object is already constructed". But if the answer is "not constructed yet" then you don't have enough information because what you really wanted to know is that it's "not constructed yet and no other thread is intending to construct it shortly". So you use the outer check as a very quick initial test and you initiate the proper, bug-free but "expensive" procedure (lock then check) only if the answer is "no".

上述实现对于大多数情况来说已经足够好了,但此时最好去阅读Jon Skeet 关于 C# 中的单例的文章 也评估了其他替代方案.

The above implementation is good enough for most cases, but at this point it's a good idea to go and read Jon Skeet's article on singletons in C# which also evaluates other alternatives.

这篇关于线程安全 C# 单例模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆