views:

94

answers:

3

I have a dictionary which is filled once in a static constructor and stays unchanged ever since. I want multiple threads to be able to read values from this collection. Do I need any locking here?

+2  A: 

No. Locking is only required when you have the possibility of interleaving multiple writes or writes with reads. Reading only, with no changes at all doesn't introduce the possibility of what one thread is doing affecting what another thread is doing.

Note that this requires no writes, at all. If, say, you're using an object and reading it somehow modifies the internal state of the object as a side effect, then you'd need to have locking still.

Donnie
Though this is documented as being the case for one specific dictionary object, this is not true for dictionary objects in general. Imagine, for example, a dictionary object that when you read from it, it reorganizes its internal structure so that the recently-read object is moved to the front of the hash bucket list, so that next time it is read, it is faster. Many dictionaries written for compilers have this property because if you look up "WriteLine" inside "Console" once, odds are good you're about to look it up again. That means reads can cause mutations which might not be thread safe.
Eric Lippert
@Eric - fair, and true. I removed the word "custom" from my 2nd paragraph because, as you pointed out, many framework objects do this too.
Donnie
+1  A: 

Edit: It appears the docs say this class is thread safe for reading. But it if didn't the answer below still applies since you can't assume your read only is read only for the class.


The short answer is yes. Unless the class says it is thread safe. There are a lot of things it could be doing that are not thread safe.

It's likely it won't cause a problem but the class could be using internal variables in a way that could cause race conditions. It could also be calling other classes that are not thread safe. Unless you check the code of the docs says it's OK then it is not safe to assume.

For example you may think it is read only but the class trying to speed things up may cache the last item accessed which involves writting data. That could fail causing you to retrieve a different item than expected.

Again I don't think that is likely here but unless the class says it is thread safe it is dangerous to assume.

Kevin Gale
Does this mean that if I change some properties of an object contained in the Dictionary I can get an exception?
You should TEST THOROUGHLY, but many collections can be read concurrently safely even if they're not labeled as "thread safe". Assuming it is dangerous can lead to worse performance for absolutely no gain.
Donnie
@user375487: You won't likely won't get an exception ,but you can get odd behavior. You should lock the object you are changing since it is possible that more than one thread may try to change it at the same time.
Donnie
+8  A: 

According to Microsoft's documentation, the Dictionary class can support multiple readers concurrently, as long as the collection is not modified. Therefore, no locks are required.

Joe Albahari
No idea why more people don't check the docs. It's the first place everyone should look. Why ask the world when you can ask the guys who wrote the code? :) +1
Kieren Johnstone