Mystic
Mystic

Reputation: 5124

Synchronizing on shared data structure

Consider code that involves multiple threads writing to a shared data structure. Now each of these threads write objects to the shared container that are essentially unique. Take the following (fictitious) example:

class Logger
{
   IDictionary<string, Log> logDictionary = new Dictionary<string, Log>();

   // Method called by several other threads
   void AddLog(Log log)
   {
      logDictionary[log.ID] = log;
   }

   // Method called by a separate thread
   IList GetLog(/*some criteria*/)
   {
      // loop through logDictionary and
      // create an IList based on criteria
   }
}

I understand clearly that concurrent access to a shared object can be a problem if multiple threads try to update the same 'variable' (or slot) leading to race conditions. Now my question has 3 parts.

(1) Is synchronization necessary if the threads are making blind updates? (Even if they are updating the same slot/variable)?

(2) Is it thread-safe to assume, given that each thread is writing a unique object, there is no need to synchronize access to the shared dictionary/container?

(3) Does the call to GetLog() by another thread, really pose problems even if the dictionary is being updated simultaneously by other threads?

Upvotes: 1

Views: 2168

Answers (3)

Marc Gravell
Marc Gravell

Reputation: 1062865

The biggest problem would be if any of the threads added/removed a key in the dictionary. This could cause significant re-building internally (quite possibly breaking any competing reads and writes that are in progress), so yes; you do need to synchronize access. You might be OK if all the threads are reading/writing against existing keys, but I don't think it would be guaranteed.

I don't know about java, but in C# there is ReaderWriterLockSlim which may (if you absolutely need it) allow multiple concurrent readers or one writer (not both) - but it is often simpler (and sometimes even quicker) just to go mutex (via lock etc).

edit

Also - for strongly-typed dictionary types (i.e. generics etc), with value-types that are over-sized, the update won't be interlocked; another thread could in theory see an in-progress update of such a value. For example, a guid on x86, etc.

Upvotes: 4

Mark Probst
Mark Probst

Reputation: 7367

The container classes in C# are not thread-safe for writing, which means that you MUST make sure that only one thread accesses a container class instance at the same time, even if each thread writes to a different key in the dictionary.

For reading, Dictionary is thread safe, i.e. you can read from the dictionary from multiple threads at the same time. It is not safe to read and write at the same time, though.

Details here.

Upvotes: 3

janneb
janneb

Reputation: 37208

1) What do you mean by "blind update"?

2) No. Assuming that Dicitonary is implemented with a hash table, you need to synchronize access in order to handle hash collisions, increasing the size of the table etc. You might be able to get away with locking individual elements in the table rather than a shared lock for the entire data structure in some cases, but that has overhead as well.

3) Depends if the updating is atomic or not.

Upvotes: 1

Related Questions