Reputation: 127
As per my knowledge while performing non-select operation in HashMap
and ConcurrentHashMap
, the ConcurrentHashMap
blocks the entire Segments
(by default-16)?
Upvotes: 2
Views: 308
Reputation: 15141
The difference is that HashMap
is not thread-safe, which means that if you have several threads using it you need to take care of concurrent operations yourself. You can easily make it thread-safe using Collections.synchronizedMap(map)
which creates a wrapper object, in which all methods are synchronized
(on that wrapper object) and delegate to the wrapped map. As you can figure out this means poor performance as only one thread (reader or writer doesn't matter) has access to it.
As you pointed out ConcurrentHashMap
is thread-safe and tries to handle synchronization a bit differently than Collections.synchronizedMap()
. Instead of a single lock it tries to use multiple locks by partitioning the underlying map into buckets and having a lock per bucket. With that several threads can use the map concurrently without problems as they might be working on records in different buckets. In this case you don't need to lock the whole map (all buckets) but only the bucket in which the record you are interested in resides, which means that you can perform a parallel operation on all buckets at the same time. Obviously if all threads are working on the same record (or the same bucket) they will still be synchronized like in Collections.synchronizedMap()
and will be blocked on writes. This approach is really good when the number of your reader threads outnumbers writer threads.
For instance you might have (very simplified):
ConcurrentHashMap = [ bucket1 = [r1->x], bucket2 = [r2->y], bucket3 = [r3, z] ]
When you are doing a read/write operation for entry with key r1 the map will choose bucket1 as that record should be there and lock bucket1 and only bucket1. Then when another thread comes if it queries for r2 it can safely do so but if it queries for r1 also it has to wait as bucket1 is locked.
Of course there's a performance penalty behind all of this but it's not terribly high (although I don't have any benchmarks to back this statement).
Does that answer your question?
Upvotes: 3
Reputation: 2047
ConcurentHashMap has different structure than simple HashMap. A ConcurrentHashMap is divided into number of segments (16 by default) on initialization.
It allows similar number of threads to access these segments concurrently so that each thread work on a specific segment.
While one thread is working on one segment it puts a lock on it. It does not block the rest of the segments.
If you want to read more about it, I suggest link below - good explanation with clear examples
Upvotes: 0
Reputation: 7196
No,In case of non select(EX. put) operation also,Lock is always taken at the segment level.
You can see the ConcurrentHashMap source code.
Whenever you call put() method on concurrent hashmap it first calculate hash position for the particular segment,then calls trylock() method on that segment only, not at the table level.
Upvotes: 0