Why Changing int to Integer Lets a Non‑volatile Java Loop Terminate
This article explores a classic Java concurrency puzzle where a non‑volatile flag causes an infinite loop, examines how modifying the loop variable from int to Integer or adding volatile affects termination, and explains the underlying JVM memory‑barrier behavior revealed by DeepSeek.
Problem Statement
The original code defines a static boolean flag set to false and a static int i initialized to 0. The main thread continuously increments i in a while (!flag) loop while a child thread sleeps 100 ms then sets flag = true and prints a message.
Because flag is not declared volatile, the main thread may never see the update, resulting in a dead loop—a classic interview question.
First Micro‑adjustment
The author marks i as volatile (leaving flag non‑volatile). The program now terminates, but the reason is unclear.
Second Micro‑adjustment
Changing i from the primitive int to the wrapper Integer (without any volatile) also makes the program terminate.
DeepSeek Investigation
Feeding the original code to DeepSeek yields a correct explanation of the dead loop and the need for volatile on flag.
When i is an Integer, each i++ creates a new Integer object and updates the reference. Some JVM implementations (e.g., HotSpot) perform a hidden memory barrier on reference writes, which can inadvertently synchronize other variables, allowing the main thread to observe flag = true and exit the loop.
DeepSeek also explains that the putstatic instruction, which updates a static field, triggers this barrier for object references but not for primitive fields.
JVM‑Level Explanation
According to the Java Memory Model (JMM), ordinary reads and writes only require loading from or flushing to main memory; they do not enforce visibility for non‑volatile variables. However, certain JVM actions—such as object reference assignment, method calls, or memory allocation—may implicitly include a memory barrier, causing the working memory to synchronize with main memory.
HotSpot’s implementation adds such a barrier on putstatic for reference types, which explains why changing i to Integer or marking i as volatile both lead to program termination.
Conclusion
The observed behavior is not guaranteed by the JMM; it depends on JVM-specific optimizations. Adding volatile to flag is the reliable solution, while the other tricks work only on JVMs like HotSpot that introduce hidden memory barriers.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Su San Talks Tech
Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
