1

我知道何时在 C# 中使用 lock 块,但我不清楚的是lock variablelock 语句的括号中。考虑以下Singleton Design PatternDoFactory :

class LoadBalancer
{
   private static LoadBalancer _instance;
   private List<string> _servers = new List<string>();
   private static object syncLock = new object();
   public static LoadBalancer GetLoadBalancer()
   {
   // Support multithreaded applications through
   // 'Double checked locking' pattern which (once
   // the instance exists) avoids locking each
   // time the method is invoked
   if (_instance == null)
   {
    lock (syncLock)
    {
      if (_instance == null)
      {
        _instance = new LoadBalancer();
      }
    }
   }

  return _instance;
 }
}

在上面的代码中,我不明白为什么我们不使用_instance锁变量而不是`syncLock?

4

3 回答 3

12

在上面的代码中,我不明白为什么我们不使用 _instance 作为锁变量而不是 `syncLock?

那么你会试图锁定一个空引用,一方面......

此外,您将通过可变字段锁定,这是一个坏主意。(如果该字段更改了值,那么另一个线程可以进入相同的代码。不是很好。)通过只读字段锁定通常是个好主意。

此外,您将锁定一个引用,该引用返回给调用者,调用者可以任意长时间持有锁定。我更喜欢锁定一个永远不会暴露在类之外的引用,比如syncLock.

最后,由于 CLI 内存模型,这个实现无论如何都被破坏了。(它可能会或可能不会在 MS 实现中被破坏,这有点强。我不想打赌。)_instance变量应该被标记为volatile好像你真的想使用这种方法......但我' d 个人无论如何都要避免双重检查锁定。有关更多详细信息,请参阅我关于单例模式的文章。

于 2013-07-30T14:59:53.340 回答
0

我自己并没有太多使用 lock 语句。

但我的猜测是,这是因为您无法锁定实例,因为它为空。

所以你必须制作静态对象'synclock',它只用于锁定你实际创建'instance'变量的部分。

于 2013-07-30T15:02:08.537 回答
0

这是我的一般风格偏好 - 只要有可能,只锁定专门为锁定目的创建的对象。

http://www.yoda.arachsys.com/csharp/singleton.html

于 2013-07-30T15:04:52.817 回答