我正在复习一本书中的一个示例代码,发现了下面的代码(简化)。
在代码中,当调用Subscribe(T subscriber)时,线程进入一个锁段。
然后,当锁内的代码调用AddToSubscribers(T subscriber)方法时,该方法会有另一个锁。为什么需要第二把锁?

public abstract class SubscriptionManager<T> where T : class
{
   private static List<T> subscribers;
   private static void AddToSubscribers(T subscriber)
   {
      lock (typeof(SubscriptionManager<T>))
      {
         if (subscribers.Contains(subscriber))
            return;
         subscribers.Add(subscriber);
      }
   }

   public void Subscribe(T subscriber)
   {
      lock (typeof(SubscriptionManager<T>))
      {
         AddToSubscribers(subscriber);
      }
   }
}

最佳答案

在这种情况下,它不是;但是,因为锁是可重入的,这有助于确保AddToSubscribers的任何其他调用方观察锁。实际上,出于这个原因,我会说“从Subscribe中删除它,让AddToSubscribers执行锁定”。
然而!锁定Type相当危险。一块地会更安全:

// assuming static is correct
private static readonly object syncLock = new object();

以及lock(syncLock)。根据分配subscribers的时间,您也可以使用lock(subscribers)(无需额外字段)。
我还应该注意到,将实例方法添加到静态状态是相当不错的….不寻常;imoSubscribe应该是一个static方法,因为它与当前实例无关。

08-18 00:36