Fundamentals 5 min read

Analyzing the Dead Loop Issue in JDK 1.7 HashMap and Its Resolution in JDK 1.8

This article explains why the pre‑JDK 1.8 HashMap can enter an infinite loop during concurrent resizing, illustrates the problem with detailed step‑by‑step diagrams, and shows how JDK 1.8 redesigns the resize algorithm to prevent the loop.

Full-Stack Internet Architecture
Full-Stack Internet Architecture
Full-Stack Internet Architecture
Analyzing the Dead Loop Issue in JDK 1.7 HashMap and Its Resolution in JDK 1.8

In the previous article we dissected memory‑leak issues of LinkedHashMap under multithreaded read‑write locks; here we continue the deep‑dive style, now focusing on a classic concurrency problem: why HashMap before JDK 1.8 can dead‑loop under multithreading.

Part 1 – Overview of JDK 1.7 HashMap

HashMap stores entries using an array of buckets combined with linked lists to resolve hash collisions. As the number of elements grows, the map expands its internal array (ignoring load‑factor details here). After expansion, each entry must be re‑hashed and moved to the appropriate bucket in the new array.

The expansion works by allocating a new array, then re‑inserting each original entry into the new array using head‑insertion, finally replacing the old array with the new one.

The question is: why does this process cause an infinite‑loop (cycle) when performed concurrently?

Part 2 – Analyzing the Cause of the Cycle

A single animated diagram (see the GIF) illustrates the scenario.

Assume three entries <18,A>, <48,B>, <86,C> are stored in table[3] as a linked list.

Thread 1 is pre‑empted after reading the first entry (e = <18,A>, next = <48,B>). When it resumes, Thread 2 has already completed the resize, so newTable[19] now points to the list <86,C> → <48,B> → <18,A> (tail‑insertion order).

If Thread 1 continues processing the original order and inserts each element at the head of the new list, the resulting order becomes <48,B> → <18,A> → <86,C> → <48,B> → <18,A>, creating a cycle where <18,A>.next points back to <86,C> instead of null .

Consequently, a call to get(19) may traverse the list forever because the linked list has become a loop.

Part 3 – Why JDK 1.8 Does Not Form a Cycle

The JDK 1.8 resize implementation (see the screenshot) fixes the issue in two ways:

It uses tail‑insertion, preserving the original order of the linked list in the new table.

It employs a local variable to hold the element being moved and only assigns it to the new table after the move, avoiding in‑place modifications that could create a cycle.

Part 4 – Conclusion

Regardless of the version, HashMap is not thread‑safe; developers must take special precautions when using it in concurrent environments.

If you find any issues with the analysis, feel free to add me on WeChat for further discussion.

When you dig into the code line by line and uncover the root cause, there’s a unique sense of satisfaction.

JavaHashMapJDK8JDK7DataStructuresDeadLoop
Full-Stack Internet Architecture
Written by

Full-Stack Internet Architecture

Introducing full-stack Internet architecture technologies centered on Java

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.