繁体   English   中英

在写入时锁定 .NET 字典是否是线程安全的,并且读取它是无锁的?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM