Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dictionary with lock or Concurency Dictionary?

Which is preferred in a multi-threaded application: Dictionary with lock object or Concurrency Dictionary

Which is efficient and why should I use one or the other?

edit 1: Storing Guid as key and bool as value.

edit 2: more than 2 worker threads and one UI thread.

like image 978
radu florescu Avatar asked Mar 26 '12 07:03

radu florescu


4 Answers

I would say you've got the following options.

Some new Framework 4.0 classes:

  • ConcurrentDictionary. Work fast and reliable.
  • ConcurrentBag. It's unordered collection of objects, so it works faster, but suits if you don't need sorting only.
  • ConcurrentStack. It's an implementation of the classic LIFO (Last-In First-Out) data structure that provides thread-safe access without the need for external synchronization
  • ConcurrentQueue. It's a thread-safe FIFO (first in-first out) collection.

All new 4.0 classes work faster but have some features mentioned by levanovd. Performance comparison of these classes you can find here.

Some classic solutions from earlier versions:

  • Dictionary + Monitor. Simple wrap to lock
  • Dictionary + ReaderWriterLock. Better than the previous one, because has got read and write locks. So several threads can read, and just one - write.
  • Dictionary + ReaderWriterLockSlim. It's just optimisation of the previous one.
  • Hashtable. From my experience, it's the slowest method. Check Hashtable.Synchronized() method, it's a ready to go solution from Microsoft.

If I had a restriction of using Framework v3.5, I would use Dictionary + ReaderWriterLock or ReaderWriterLockSlim.

like image 172
Alex Klaus Avatar answered Sep 29 '22 00:09

Alex Klaus


Read carefully about ConcurrentDictionary. It has some unobvious features.

Here are some of them:

  • If two threads call AddOrUpdate there's no guarantees about which of factory delegates will be called and even no guarantee that if a factory delegate will produce some item that this item will be stored in dictionary.
  • Enumerator obtained by GetEnumerator call is not a snapshot and may be modified during enumeration (that doesn't cause any exceptions).
  • Keys and Values properties are snapshots of corresponding collections and may not correspond to actual dictionary state.
  • etc.

So please read about ConcurrentDictionary again and decide if this behavior is what you need.

Hope this helps!

like image 37
levanovd Avatar answered Sep 28 '22 23:09

levanovd


When you are implementing a dictionary with a lock object, your main concern seems like thread safety. So it seems, a concurrentDictionary already manages this concern. I think there is no point in re-inventing the wheel.

like image 39
daryal Avatar answered Sep 29 '22 01:09

daryal


I think both will provide thread-safety but using a Dictionary with lock object will limit the number of thread that can access the Dictionary concurrently to 1. While using Concurrent Dictionary, you can specify concurrent level (i.e. number of threads that can access the Dictionary concurrently). If performance does matter, I believe Concurrent Dictionary should be your choice.

like image 32
Thang Mai Avatar answered Sep 29 '22 00:09

Thang Mai