beginnerFoundations

How does ConcurrentHashMap achieve thread safety without locking on reads?

Since Java 8, ConcurrentHashMap stores its entries in an array of Node buckets where each node's value field is declared volatile. Because reads simply traverse the bucket chain using volatile field reads, and volatile alone guarantees visibility of the latest written value, no lock is needed at all for get() operations -- reads never block. Writes, on the other hand, only need to lock the head node of the specific bucket being modified: the very first insertion into an empty bucket is done with a compare-and-swap, and subsequent insertions into an already-occupied bucket use a synchronized block scoped to that bucket's head node. This means reads never block behind writes, and writes to different buckets never contend with each other at all. One consequence of this design is that the map's overall size is tracked using a distributed counter similar to LongAdder, which makes size() an approximate rather than perfectly exact count under concurrent modification.

Ready to master this question?

Generate a complete walkthrough — background, the full answer in plain language, a working code example explained line by line, a real-world scenario, common mistakes, and how this same question gets asked in different ways.

Sign in to generate a response

Next Step

Continue to What is the difference between submit() and execute() on an ExecutorService?← Back to all Java Concurrency & Multithreading questions