我的团队目前正在讨论这个问题。
有问题的代码是
if (!myDictionary.ContainsKey(key))
{
lock (_SyncObject)
{
if (!myDictionary.ContainsKey(key))
{
myDictionary.Add(key,value);
}
}
}
我看到的一些帖子说这可能是一个很大的 NO NO(当使用 TryGetValue 时)。然而,我们团队的成员说这没问题,因为“ContainsKey”不会迭代 key 集合,而是通过 O(1) 中的哈希码检查 key 是否包含在内。因此他们声称这里没有危险。
我想听听您对这个问题的诚实意见。
最佳答案
不要这样做。这不安全。
您可能正在调用 ContainsKey
来自一个线程,而另一个线程调用 Add
. Dictionary<TKey, TValue>
根本不支持这一点.如果Add
需要重新分配存储桶等,我可以想象您可能得到一些非常奇怪的结果或异常。它可能是以您看不到任何不良影响的方式编写的,但我不想依赖它。
使用双重检查锁定对字段进行简单的读/写是一回事,尽管我仍然反对它 - 调用已明确描述为 不是 对多个并发调用是安全的。
如果您使用的是 .NET 4, ConcurrentDictionary
可能是前进的方向。否则,只需锁定每次访问即可。
关于c# - 双重检查字典 "ContainsKey"上的锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6018768/