Home > Back-end >  Is it thread-safe to lock a .NET Dictionary on write, and read it lock-free?
Is it thread-safe to lock a .NET Dictionary on write, and read it lock-free?

Time:08-22

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).

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).

CodePudding user response:

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. 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.

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. 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.

  • Related