当前位置:  开发笔记 > 编程语言 > 正文

使用锁定Dictionary <string,object>的键

如何解决《使用锁定Dictionary<string,object>的键》经验,为你挑选了2个好方法。

我有一个Dictionary.

编辑:有人向我指出,我的榜样很糟糕.我的全部意图不是更新循环中的引用,而是根据需要更新/获取数据的不同线程更新不同的值.我将循环更改为方法.

我需要更新我的字典中的项目 - 一次一个键,我想知道在我的Dictionary对象的.key值上使用锁是否有任何问题?

private static Dictionary matrixElements = new Dictionary();

//Pseudo-code

public static void UpdateValue(string key)
{
    KeyValuePair keyValuePair = matrixElements[key];
    lock (keyValuePair.Key)
    {
        keyValuePair.Value  = SomeMeanMethod();
    }
}

这会在法庭上举行还是失败?我只是希望字典中的每个值都被独立锁定,因此锁定(和更新)一个值不会锁定其他值.此外,我知道锁定将持续很长时间 - 但数据将无效,直到完全更新.



1> Philip Rieck..:

锁定在代码锁定之外可访问的对象是一个很大的风险.如果任何其他代码(任何地方)锁定该对象,您可能会遇到一些难以调试的死锁.还要注意你锁定对象,而不是引用,所以如果我给你一个字典,我仍然可以保持对键的引用并锁定它们 - 导致我们锁定同一个对象.

如果你完全封装字典,并自己生成密钥(它们不会被传入,那么你可能是安全的.

但是,请尽量遵守一条规则 - 尽可能将锁定对象的可见性限制为锁定代码本身.

这就是你看到这个的原因:

public class Something
{
  private readonly object lockObj = new object();

  public SomethingReentrant()
  {
    lock(lockObj)    // Line A
    {
      // ...
     }
   }
}

而不是看到上面的A行被替换为

  lock(this)

这样,锁定了单独的对象,并且可见性受到限制.

编辑 Jon Skeet正确地观察到上面的lockObj应该是readonly.


我想补充一点,lockObj也几乎总是被声明为readonly.

2> Sander..:

不,这不行.

原因是字符串实习.这意味着:

string a = "Something";
string b = "Something";

都是同一个对象!因此,你永远不应该锁定字符串,因为如果程序的其他部分(例如同一个对象的另一个实例)也想要锁定同一个字符串,你可能会在不需要它的情况下意外地创建锁争用; 甚至可能陷入僵局.

不过,请尽量使用非字符串.为了最清楚,我总是创建一个单独的锁定对象,这是个人习惯:

class Something
{
    bool threadSafeBool = true;
    object threadSafeBoolLock = new object(); // Always lock this to use threadSafeBool
}

我建议你这样做.使用每个矩阵单元的锁定对象创建一个Dictionary.然后,在需要时锁定这些对象.

PS.改变你正在迭代的集合并不是很好.它甚至会抛出大多数集合类型的异常.尝试重构这个 - 例如迭代一个键列表,如果它始终是常量,而不是对.

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有