【问题标题】:Getting a lock on a single dictionary entry instead of whole dictionary?锁定单个字典条目而不是整个字典?
【发布时间】:2011-04-19 22:52:11
【问题描述】:

假设我有一个static Dictionary<string, object> 并想要执行以下操作,但我只想锁定我当前正在处理的特定字典条目而不是整个字典:


lock(myDictionary)
{
   if(myDictionary["myKey"] == null)
   {
      myDictionary["myKey"] = new MyClass();
   }
}

如果不编写我自己的 Dictionary 实现,这可能吗?

谢谢,

【问题讨论】:

    标签: c# thread-safety locks


    【解决方案1】:

    您可以使用新的ConcurrentDictionary<TKey,TValue> 类。它通过以比锁定整个字典更细粒度的方式锁定来有效地提供线程安全。

    【讨论】:

    • 谢谢,我不知道这个。我实际上是在尝试更新 ASP.NET 应用程序以使线程安全地使用 Session 状态,并希望有一种方法可以锁定 Session 对象的一部分而不是整个对象。看起来我将不得不编写自己的 SessionState 实现。
    • @nw 从并发的角度来看,您确定 ASP.NET 会话状态真的是个问题吗?而是先阅读msdn.microsoft.com/en-us/library/ms178581.aspx 底部的“并发请求和会话状态”段落。
    • 我要解决的主要问题是来自同一会话的请求排队,因此服务器在取消 ajax 请求后会长时间阻塞。当我开始这个线程时,我在想有一种方法可以关闭这个队列并且我可以自己管理并发,但显然这很困难或不可能。会话状态仅用于为每个会话存储一个缓存对象。现在我认为最简单的解决方案是在应用程序状态中放置一个 ConcurrentDictionary,将会话 ID 映射到缓存对象。你怎么看?
    • @nw:你可以尝试这样做,但是你会遇到确保它正确清除的问题,否则你会导致内存泄漏。如果您可以使该部分正常工作,那么从技术上讲,它应该可以工作。
    【解决方案2】:

    【讨论】:

      【解决方案3】:

      在您的情况下,仅“锁定特定字典条目”是没有意义的;即使您编写自己的实现。如果您不知道该条目是否存在并且您想在这种情况下将其添加到字典中,您将始终必须同步对字典控制结构的访问。换句话说,即使您自己实现它,也需要同步对其内部结构的至少特定部分的访问。

      【讨论】:

      • 我希望字典内部结构的某个特定部分可以锁定。字典是用某种哈希表实现的吗?例如,如果键的哈希是列表数组的索引(以处理哈希冲突),那么我可以锁定与我的键关联的特定列表,对吗?
      • 是的,根据特定的技术实现,字典必须锁定某些特定的子结构。
      猜你喜欢
      • 2011-08-02
      • 2021-11-30
      • 2019-11-04
      • 2015-12-25
      • 1970-01-01
      • 2021-12-25
      • 2012-04-09
      • 1970-01-01
      • 2011-07-15
      相关资源
      最近更新 更多