HashMap Internals & Locks
KOTLIN › Concurrency
HashMap internals, why it breaks under threads, choosing the right map, memory visibility, and locks.
The classic live-coding trap is a thread-safe cache: interviewers check you know how HashMap works inside (buckets, hashCode/equals, resize), what exactly goes wrong when threads share one, and how to fix it with ConcurrentHashMap (which has its own deep-dive topic), atomics or a lock. The follow-ups are about the WHY: visibility, happens-before, and check-then-act races. Candidates fail this area on thread memory sync more than on syntax, so be ready to explain what volatile does and does not guarantee.
What this covers
- HashMap internals: hashCode picks the bucket, equals resolves collisions within it, load factor (0.75) triggers resize, and long chains treeify (Java 8+)
- The hashCode/equals contract: equal objects must share a hashCode, and mutating a key after insertion strands the entry in the wrong bucket
- Why a shared HashMap breaks: lost updates, stale reads (visibility), and corruption when two threads trigger a resize together
- volatile guarantees visibility and ordering, never atomicity: check-then-act and read-modify-write still race and need atomics, compute-style methods, or a lock
- happens-before edges: unlock then lock of the same monitor, volatile write then read, Thread.start() and Thread.join()
- Choosing the map: HashMap by default, LinkedHashMap for order and easy LRU caches, TreeMap for sorted keys, and ConcurrentHashMap (its own topic) the moment threads share it
- Lock choice: synchronized/Mutex for simple exclusion, ReentrantReadWriteLock for read-heavy workloads (many readers OR one writer), and coroutine Mutex instead of blocking locks in suspend code
Study this topic
- HashMap Internals & Locks explained: the guided lesson
- 14 practice quiz questions
- 9 revision flashcards
- HashMap Internals & Locks interview questions and answers