简体   繁体   English

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

[英]Is it thread-safe to lock a .NET Dictionary on write, and read it lock-free?

I know that dictionaries are not thread safe.我知道字典不是线程安全的。

But for sake of simplicity I sometimes (when the scenario is not too complex) wrap them around a lock and used it in multi-thread environment even if other concurrent structure may be used (eg: ConcurrentDictionary ).但是为了简单起见,我有时(当场景不太复杂时)将它们包裹在一个锁周围并在多线程环境中使用它,即使可以使用其他并发结构(例如: ConcurrentDictionary )。

Here an example of what I am doing:这是我正在做的一个例子:

 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;
     }
}

I am afraid that maybe even reading the dictionary while writing, may produce inconsistent data.恐怕连边写边看字典,都可能产生不一致的数据。
I am not scared about reading old data, and not "seeing" the new one (till the write end) that's ok in my scenario.我不害怕阅读旧数据,也不害怕“看到”新数据(直到写入结束),这在我的场景中是可以的。
Even if the new data is the only inconsistent one (till the write operation end) it's ok.即使新数据是唯一不一致的数据(直到写操作结束)也没关系。
What I am concerned about is that maybe the dictionary structure is in a usable state while inserting (and so a read in that moment will produce a complete messed up result even for very old key and not only the new one).我担心的是字典结构在插入时可能位于可用的 state 中(因此,即使对于非常旧的密钥而不仅仅是新密钥,在那一刻的读取也会产生完全混乱的结果)。

No, it's not thread-safe.不,它不是线程安全的。 The Dictionary<TKey,TValue> is thread-safe for multiple readers, only if it's in a permanent immutable ("frozen") state. Dictionary<TKey,TValue>对多个阅读器来说是线程安全的,前提是它位于永久不可变(“冻结”)state 中。 If you want to read and write into a dictionary from multiple threads concurrently, then you must lock invariably on all operations (read and write), otherwise the behavior of your program is undefined.如果要同时从多个线程读取写入字典,则必须始终lock所有操作(读取写入),否则程序的行为是未定义的。

Locking is fast : you can expect to acquire and release a lock in as little as 20 nanoseconds on a 2010-era computer if the lock is uncontended. 锁定速度很快:在 2010 年代的计算机上,如果锁没有争用,您可以期望在短短 20 纳秒内获取和释放锁。 So you shouldn't worry too much about the performance of your app, when its correctness is at stake.¹因此,当应用的正确性受到威胁时,您不必过于担心应用的性能。¹

¹ Locking is fast, but not without cost. ¹锁定速度很快,但并非没有成本。 If your app is expected to do millions of read and write operations per second on the same dictionary, switching to a ConcurrentDictionary<K,V> will be most likely significantly beneficial for the performance of your app.如果您的应用预计每秒对同一个字典执行数百万次读取和写入操作,那么切换到ConcurrentDictionary<K,V>很可能对您的应用性能有很大的好处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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