BT

ConcurrentDictionary, .NET 4.0’s New Thread-Safe Hashtable

by Jonathan Allen on Jan 23, 2010 |

The ConcurrentDictionary is a cornerstone in .NET 4.0’s greatly increased emphasis on parallel and concurrent programming. But before we delve into it, we offer a review of the problems in previous versions of .NET.

The first version of the hash table in .NET was System.Collections.Hashtable. While it wasn’t thread-safe, you could in theory get a thread-safe wrapper simply by calling Hashtable.Synchronized. Unfortunately this wrapper wasn’t actually thread-safe because of the way it was used.

Say, for example, you wanted to check if a key exists in the collection. If not, then you want to perform a non-repeatable operation, the result of which would be stored there. Even though both ContainsKey and set_Item are independently thread-safe, there is no way to directly compose them. Instead you have to take a lock on the SyncRoot, negating the whole reason you asked for a synchronized version in the first place.

When .NET 2.0 introduced generics and System.Collections.Generic.Dictionary, Microsoft punted the issue. Developers had to take explicit locks on their own or just

.NET 3.5 didn’t add anything techniques, but it did make them a whole lot easier to implement with the increased emphasis on functional programming. First of all, the idea of defining custom delegates disappeared. From that point on any well designed API would be expected to reuse the generic Action and Func delegates. Another benefit was the introduction of lambda notation to VB and a greatly improved notation in C#. As a result, developers could easily create their own synchronized wrappers with APIs such as this:

public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)

Unlike the earlier versions where developers had to muck about with locks, this method on the new ConcurrentDictionary looks like it hard to use incorrectly. Simply provide a key and a delegate that will be executed if the key doesn’t exist. A long as the function itself is thread-safe, everything should be atomic.

Well, no. To “avoid the myriad of problems that can arise from executing unknown code under a lock”, the valueFactory delegate isn’t executed under the locks. So there is the possibility of a race condition and developers need to ensure that the valueFactory delegate only performs repeatable operations.

If you need this functionality, you have to combine the ConcurrentDictionary class with the Lazy class. An example of this is included in the AsyncCache class, which is being shipped as a sample.

While subject to change, currently the ConcurrentDictionary class is implemented with lock-free reads. To improve performance, developers can provide an estimated number of writer threads. This will govern how many fine-grained locks the hash table uses.

You can learn more about the ConcurrentDictionary from Stephen Toub’s post.

Hello stranger!

You need to Register an InfoQ account or to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

or just "what"? by 侯 伯薇

In the 4th paragraph, it seems not ends normally,
"Developers had to take explicit locks on their own or just...",just what?

Little mistake by Jerome St-Pierre

I think it was meant to say: "As long as the function..." instead of "A long as the function...".

Thanks for the article thought.

Has C# Jumped The Shark? by John DeHope

When I read stuff like this, I have to ask myself, is it time to start learning a language that was written to handle concurrency from day one? Things like this really feel shoehorned in.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

3 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2013 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT