1

我正在努力使我的 SortedDictionary 线程安全,但我不确定的是:在一个线程中调用添加到 SortedDictionary 是否安全,如下所示:

dictionary.Add(key, value);

并简单地在另一个线程中从此字典中获取一个项目,如下所示:

variable = dictionary[key];

在这两个地方都没有明确的枚举,所以看起来很安全,但最好能确定一下。

4

4 回答 4

2

不,并发读取和写入是不安全的SortedDictionary<K,V>:将元素添加到排序字典可能涉及树的重新平衡,这可能会导致并发读取操作在导航到感兴趣的元素时转向错误。

为了解决这个问题,您需要将 的实例包装SortedDictionary<K,V>在执行显式锁定的类中,或者滚动您自己的与SortedDictionary<K,V>.

于 2013-07-17T14:15:24.977 回答
1

不。任何修改树的东西都不是线程安全的。诀窍是在一个线程中填充 SortedDictionary,然后将其视为不可变并让多个线程从中读取。(您可以使用 SortedDictionary 执行此操作,如此处所述。我提到一点是因为可能有一个集合/字典/映射在某处被读取时发生更改,因此您应该经常检查。)

如果您需要在它被释放到野外后对其进行修改,那么您就有问题了。您需要锁定它才能对其进行写入,并且所有读者都需要尊重该锁定,这意味着他们也需要锁定它,这意味着读者不能再同时读取它。 解决这个问题的最好方法通常是创建一个全新的 SortedDictionary,然后,一旦新的是不可变的,就用对新的引用替换对原始的引用。(您需要一个 volatile 引用才能正确执行此操作。)读者将干净地切换字典而不会出现问题。直到最后一位读者读完并发布参考资料,旧词典才会消失。

(有 n-readers 和 1-writer 锁,但您希望完全避免任何锁定。)

(请记住,如果您正在枚举,对字典的引用可能会突然改变。为此使用局部变量而不是引用(易失性)引用。)

Java 有一个ConcurrentSkipListMap,它允许任意数量的同时读取和写入,但我认为.NET 中还没有类似的东西。如果有的话,它的读取速度无论如何都会比不可变的 SortedDictionary 慢。

于 2013-07-17T21:04:22.763 回答
1

不,因为它没有被证明是安全的。这才是真正的原因。对实现细节进行推理并不那么好,因为它们是你不能依赖的细节。

于 2013-07-17T21:31:48.873 回答
0

不,这样做是不安全的。如果你想在多线程中实现,那么你应该这样做

 private readonly object lockObject = new object();
 lock (lockObject )
    {
        //your dictionary operation here.
    }
于 2013-07-17T14:16:04.500 回答