Java中HashMap重哈希时添加元素:阻塞还是非阻塞?
Awesome question! Let's dive into how Java's HashMap handles resizing (the rehashing process you're asking about) when you try to add elements mid-operation. I'll break this down by single-threaded and multi-threaded scenarios since that's where the key differences lie.
How HashMap Handles Rehashing + Element Addition
Single-Threaded Scenario: Serial, "Complete Rehash First" Behavior
In a single-threaded context (the intended use case for HashMap), the process is straightforward and sequential:
- When you call
put(K key, V value), HashMap first checks if adding this new element would push the load factor past its threshold (default 75% of capacity). - If it does, the
resize()method kicks off immediately. This involves:- Creating a new array (usually double the original capacity)
- Rehashing every existing element in the old array and placing them into the new array's buckets
- Crucially, the entire resize/rehash process completes before the new element is inserted into the array. There's no "mid-rehash addition" here because the single thread can only do one thing at a time—think of it as finishing the full relocation before unpacking the new item.
- This isn't "blocking" in the concurrency sense; it's just normal sequential execution of the put logic.
Multi-Threaded Scenario: Undefined Behavior (No Safeguards)
HashMap is not thread-safe—it has no built-in locks or synchronization. So if multiple threads are messing with it at the same time (one resizing, another trying to put an element), bad things happen:
- Thread B might start a put operation while Thread A is in the middle of resizing. Thread B could calculate the bucket position based on the old array's capacity, insert the element into the old array, and then Thread A's resize finishes overwriting that array—resulting in data loss.
- A classic issue is the "infinite loop" bug: concurrent resizing can create circular linked lists in buckets, which causes subsequent
get()calls to loop forever. - There's no intentional "allow mid-addition" behavior here; this is just a side effect of HashMap lacking concurrency controls. The JDK documentation explicitly warns against using HashMap in multi-threaded environments.
Key Takeaway
- For single-threaded code: HashMap will always finish rehashing the entire existing collection before adding the new element that triggered the resize.
- For multi-threaded code: Don't use HashMap. Use
ConcurrentHashMapinstead—it handles concurrent resizes and inserts safely with lock-striping and other optimizations.
内容的提问来源于stack exchange,提问作者Manoj Kumawat
相关产品推荐
相关产品推荐

