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

查看:202
本文介绍了线程安全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;
      }
   }
}

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

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.

以这种方式想到:裸 null 检查(不含锁定)只有当答案为是时,才能保证正确的可用答案,对象已经构建。但是,如果答案是尚未构建,那么您没有足够的信息,因为您真正想知道的是它尚未构造,而不是其他线程打算很快构造 。所以你使用外部检查作为一个非常快速的初始测试,只有答案为否时,才启动正确的,无错误但昂贵的程序(锁定然后检查)。

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天全站免登陆