[英]Is it thread-safe to lock a .NET Dictionary on write, and read it lock-free?
我知道字典不是线程安全的。
但是为了简单起见,我有时(当场景不太复杂时)将它们包裹在一个锁周围并在多线程环境中使用它,即使可以使用其他并发结构(例如: ConcurrentDictionary
)。
这是我正在做的一个例子:
public class Example
{
private object _sync = new object();
private Dictionary<string,stirng> _dictionary = new Dictionary<string,string> ();
public void Write (string key, stirng value)
{
lock(_sync)
{
if (_dictionary.ContainsKey(key) == false)
_dictionary.Add(key,value);
}
}
public string Read (string key)
{
if (_dictionary.ContainsKey(key))
return _dictionary[key];
return null;
}
}
恐怕连边写边看字典,都可能产生不一致的数据。
我不害怕阅读旧数据,也不害怕“看到”新数据(直到写入结束),这在我的场景中是可以的。
即使新数据是唯一不一致的数据(直到写操作结束)也没关系。
我担心的是字典结构在插入时可能位于可用的 state 中(因此,即使对于非常旧的密钥而不仅仅是新密钥,在那一刻的读取也会产生完全混乱的结果)。
不,它不是线程安全的。 Dictionary<TKey,TValue>
对多个阅读器来说是线程安全的,前提是它位于永久不可变(“冻结”)state 中。 如果要同时从多个线程读取和写入字典,则必须始终lock
所有操作(读取和写入),否则程序的行为是未定义的。
锁定速度很快:在 2010 年代的计算机上,如果锁没有争用,您可以期望在短短 20 纳秒内获取和释放锁。 因此,当应用的正确性受到威胁时,您不必过于担心应用的性能。¹
¹锁定速度很快,但并非没有成本。 如果您的应用预计每秒对同一个字典执行数百万次读取和写入操作,那么切换到ConcurrentDictionary<K,V>
很可能对您的应用性能有很大的好处。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.