我正在复习一本书中的一个示例代码,发现了下面的代码(简化)。
在代码中,当调用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)
(无需额外字段)。我还应该注意到,将实例方法添加到静态状态是相当不错的….不寻常;imo
Subscribe
应该是一个static
方法,因为它与当前实例无关。