我正在努力使我的SortedDictionary线程安全,而我不确定的是:在一个线程中调用添加到SortedDictionary是否安全,如下所示:
dictionary.Add(key, value);
并在另一个线程中从这个字典中获取一个项目,如下所示:
variable = dictionary[key];
这两个地方都没有明确的枚举,所以它看起来很安全,但要确定它是很好的。
答案 0 :(得分:1)
不,同时读取和写入SortedDictionary<K,V>
是不安全的:向排序字典添加元素可能涉及树的重新平衡,这可能导致并行读取操作在导航时出错感兴趣的元素。
为了解决这个问题,您需要在执行显式锁定的类中包装SortedDictionary<K,V>
的实例,或者使用与SortedDictionary<K,V>
实现的接口兼容的滚动自己的集合。
答案 1 :(得分:1)
没有。修改树的任何东西都不是线程安全的。诀窍是在一个线程中填充SortedDictionary,然后将其视为不可变,并让多个线程从中读取。 (您可以使用SortedDictionary执行此操作,如here所述。我提到这一点是因为可能有一个集合/字典/地图在某处被读取时会被更改,因此您应该始终检查。)
如果你需要修改它,一旦它被释放到野外,你就会遇到问题。你需要锁定它来写入它,并且所有读者都需要尊重这个锁,这意味着他们也需要锁定它,这意味着读者不能再同时读取它。 围绕此的最佳方法通常是创建一个全新的SortedDictionary,然后,一旦新的SortedDictionary不可变,将引用替换为对原始引用的引用。 (你需要一个易变的参考来做到这一点。)读者将干净地切换字典没有问题。在最后一位读者完成阅读并发布其参考资料之前,旧词典不会消失。
(有n个读者和1个作家锁,但你想要避免任何锁定。)
(请记住,如果你要枚举,对字典的引用会突然改变。使用局部变量而不是引用(volatile)引用。)
Java有一个ConcurrentSkipListMap,允许任意数量的同时读写,但我认为.NET中还没有类似的东西。如果有,那么读取的速度要比不可变的SortedDictionary慢。
答案 2 :(得分:1)
不,因为记录是安全的。这才是真正的原因。实施细节的推理不是很好,因为它们是您不能依赖的细节。
答案 3 :(得分:0)
不,这样做是不安全的。如果你想在多线程中实现而不是你应该这样做
private readonly object lockObject = new object();
lock (lockObject )
{
//your dictionary operation here.
}