Collections Framework
Concurrent Collections
Analyze java.util.concurrent structures, ConcurrentHashMap segment evolution, and thread safety mechanisms.
Interview: Focuses on ConcurrentHashMap locks evolution (lock striping vs CAS), CopyOnWriteArrayList array copies, and BlockingQueue patterns.
The java.util.concurrent package provides thread-safe collections designed for high-concurrency systems. These collections use advanced synchronization techniques like lock-free CAS operations and lock striping, offering better performance than synchronized wrappers.
ConcurrentHashMap
Uses Compare-And-Swap (CAS) and node-level locks in Java 8+, allowing concurrent threads to write to different buckets without blocking.
CopyOnWriteArrayList
Creates a new copy of the underlying array on every modification, making it suitable for read-heavy, write-rare scenarios.
BlockingQueue
Supports operations that block when retrieving from empty queues or inserting into full queues, simplifying producer-consumer patterns.
ConcurrentHashMap evolution
The internal synchronization strategy of ConcurrentHashMap has evolved to improve concurrency:
- Java 7 (Lock Striping): The map was divided into 16 lock segments. Threads writing to different segments could execute concurrently. However, threads writing to the same segment were blocked.
- Java 8 (CAS & Node Locks): Replaced segment locks with CAS (Compare-And-Swap) operations for empty buckets, and node-level
synchronizedlocks for colliding insertions. This allows concurrent writes to different buckets in the same segment.
Common Pitfalls
- Using CopyOnWriteArrayList for write-heavy logic: Performing thousands of write operations on a CopyOnWriteArrayList, which triggers constant array allocations and degrades performance.
- Unsynchronized compound checks: Executing check-then-act operations (like
putif absent) without using atomic concurrent methods (e.g.putIfAbsent), causing race conditions.
Best Practices
- Use atomic compound methods: Always use built-in atomic methods (like
putIfAbsentorcomputeIfAbsent) when performing check-then-act operations. - Use BlockingQueue for producer-consumer: Use implementations like
ArrayBlockingQueueorLinkedBlockingQueueto coordinate work between threads without writing manual locking logic.
Interview-Relevant Information
Q1: How does ConcurrentHashMap achieve thread safety in Java 8?
Answer: It uses Compare-And-Swap (CAS) operations for inserting new nodes into empty buckets, and node-level synchronized locks for colliding entries. This avoids locking the entire map or segment, allowing high concurrency.
Q2: When should you use CopyOnWriteArrayList?
Answer: It is designed for scenarios where reads heavily outnumber writes (like listener lists). Since modifications copy the underlying array, writes are expensive, but reads are unsynchronized and fast.
Quick Checklist
Can you explain ConcurrentHashMap lock segments vs node-level locks, list copy implications in CopyOnWriteArrayList, and write a simple producer-consumer queue declaration? If yes, you understand concurrent collections.
Use Cases
Building thread-safe in-memory session stores for concurrent web servers.
Implementing messaging buffers between worker threads using BlockingQueues.
Common Mistakes
Using CopyOnWriteArrayList in write-heavy systems, causing memory pressure.
Failing to use atomic operations (like putIfAbsent) for check-then-act logic on concurrent maps.