ConcurrentHashMap to the Rescue
February 2, 2008
It was only a matter of time before I needed a Thread-safe Map. Looking at the synchronization wrappers for the Java Collections framework, I couldn’t help but be disappointed. The wrapper classes provide external synchronization on the entire Collection. That means that any read or update method is locking — one thing in at a time. What a performance bottleneck!
In contrast, the java.util.concurrent.ConcurrentHashMap class doesn’t provide any mechanism for preventing access to the entire object. According to the API documentation, retrievals will never result in locking, and insertions can frequently get by without locking. The class’s constructor provides an optional parameter for setting the concurrency level, which is described as “a hint for internal sizing.” The concurrency level should be set to the total number of expected Threads that will modify the structure.
I suspect that the only time an insertion would need to acquire a lock would be when the internal hash table has reached its load factor and needs to be resized. Thus, the Map’s actual level of concurrency must also depend on its load factor, and, consequentially, the hash function used.
There is one potential drawback (or benefit, depending on how you look at it) of the added level of concurrency. Since insertions might not lock the table, and retrievals never will, it is possible that a get operation could overlap an insertion. In this situation, the retrieval would return the value from the most recently completed insertion, which may not be the most recently begun insertion. This seems like a very small sacrifice when compared to the performance gains of the added level of concurrency, though.
For a look at the Java HashMap and Hashtable Collections, see this previous post.
Leave a Reply