I always thought that ConcurrentHashMap
and similar classes (which maintain synchronized updates and don't synchronize reads) did a very useful and intuitive thing: they did not lock reads and lock all functionality on updates. And a strategy like that does keep all things consistent.
But I read the documentation carefully, and opened the implementation of ConcurrentHashMap
, and as I understand now, it does not block reads when another thread is performing updates. And if one thread starts doing putAll(hugeCollection)
and another thread repeats contains(theSameObjectForAllCalls)
at the same time then it's more then likely that the second thread gets different results while putAll
is still working.
Here is the related part from the docs:
For aggregate operations such as putAll and clear, concurrent retrievals may reflect insertion or removal of only some entries.
Another interesting thing is that:
Retrievals reflect the results of the most recently completed update operations holding upon their onset.
This works not due to some locking, but because a new object is first being added and only after that objects counter is incremented and the object becomes visible for read operations.
So, what's the whole point of locking updates?
In ConcurrentHashMap, at a time any number of threads can perform retrieval operation but for updated in the object, the thread must lock the particular segment in which the thread wants to operate.
You should use ConcurrentHashMap when you need very high concurrency in your project. It is thread safe without synchronizing the whole map . Reads can happen very fast while write is done with a lock. There is no locking at the object level.
There can't be two threads changing things at the same time. The whole point of using such data structures is that they prevent more than one thread updating that "core internal data" at the same time. Having two threads that change the map at the very same point time is not possible.
Synchronizing those operations has no benefit here - it actually degrades performance if you don't need synchronization. The reason ConcurrentHashMap was created, is that synchronized maps (either implemented by hand like in the question or instantiated in the usual way with Collections.
Brian Goetz explained the working in an article at developer works. That should help out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With