首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >lock inside lock背后的逻辑?

lock inside lock背后的逻辑?
EN

Stack Overflow用户
提问于 2011-12-21 15:02:35
回答 4查看 357关注 0票数 5

我正在审查一本书中的示例代码,并偶然发现了以下代码(简化)。在代码中,当调用Subscribe(T subscriber)时,线程进入锁部分。然后,当锁中的代码调用AddToSubscribers(T subscriber)方法时,该方法有另一个锁。为什么第二个锁是必要的?

代码语言:javascript
复制
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);
      }
   }
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-12-21 15:08:43

在这种情况下,它不是;但是,由于锁是可重入的,这对于确保AddToSubscribers的任何其他调用者都能观察到锁很有用。实际上,出于这个原因,我会说“把它从Subscribe中删除,让AddToSubscribers来做锁定”。

然而!锁定Type是非常危险的。字段会更安全:

代码语言:javascript
复制
// assuming static is correct
private static readonly object syncLock = new object();

lock(syncLock)。根据分配subscribers的时间不同,您也可以使用lock(subscribers) (而不是额外的字段)。

我还应该注意到,将实例方法添加到静态状态是非常好的……不寻常;IMO Subscribe应该是一个static方法,因为它与当前实例无关。

票数 9
EN

Stack Overflow用户

发布于 2011-12-21 15:08:50

在您发布的代码中,这不是必需的。但话又说回来,您发布的代码是不完整的-例如,订阅者列表从未初始化。

锁定typeof(SubscriptionManager)可能也不是一个好主意--锁定subscribers字段会更好--但需要初始化subscribers字段,例如

代码语言:javascript
复制
private static List<T> subscribers = new List<T>();
票数 3
EN

Stack Overflow用户

发布于 2011-12-21 15:09:33

您可能应该阅读该示例附近的内容,看看书中谈到了什么。

对于这种特殊情况-不,第二个锁是不必要的。

注意:该示例是危险的,因为它锁定在公共对象(type)上。通常情况下,一个锁在特殊的私有对象上,所以外部代码不会因为错误地锁在同一个对象上而错误地引入死锁。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8586150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档