Why volatile and synchronized Can't Prevent Instruction Reordering in Java
An in‑depth analysis of Java’s instruction reordering versus ordered execution, illustrating how volatile ensures visibility but not atomicity, how synchronized guarantees atomicity and ordering yet cannot stop bytecode‑level reordering, with detailed DCL singleton bytecode walkthrough and multithreaded examples.
Instruction Reordering vs Ordering
Problem Description
Instruction reordering and ordering are distinct. volatile guarantees visibility and prevents reordering of its own reads/writes but does not provide atomicity. synchronized guarantees atomicity, visibility, and ordering at the lock level, yet it does not forbid low‑level CPU or JVM reordering of individual instructions.
Note: “ordering” here does not mean that instruction reordering is prohibited.
DCL Bytecode Analysis
Object creation in Java is not atomic; it consists of three steps: memory allocation, constructor invocation, and reference assignment.
Double‑checked locking code
public class MySingleton {
private static MySingleton INSTANCE;
private MySingleton() {}
public static MySingleton getInstance() {
if (INSTANCE == null) {
synchronized (MySingleton.class) {
if (INSTANCE == null) {
INSTANCE = new MySingleton();
}
}
}
return INSTANCE;
}
}Relevant bytecode (excerpt) shows that new MySingleton() expands to four bytecode instructions (lines 17, 20, 21, 24). Line 17 allocates memory, line 21 invokes the constructor, and line 24 stores the reference into the static field.
The JVM may reorder these steps (e.g., 17‑24‑21) for performance.
Problems Caused by Reordering
Thread t1 may store the reference in INSTANCE before the constructor runs.
Thread t2 sees a non‑null INSTANCE, returns it, and uses an incompletely constructed object, leading to unpredictable behavior.
Reordering is harmless in a single‑threaded context but can produce subtle bugs in multithreaded scenarios.
Ordering Guarantees of synchronized
synchronizeddoes not prevent low‑level reordering; instead it provides a higher‑level ordering by converting concurrent method calls into serial execution under a monitor lock.
Code Example Demonstrating Serial Execution
public class MySingleton {
private static MySingleton INSTANCE;
private MySingleton() {}
public static MySingleton getInstance() {
if (INSTANCE == null) {
synchronized (MySingleton.class) {
if (INSTANCE == null) {
INSTANCE = new MySingleton();
}
}
}
return INSTANCE;
}
public static void test(final MySingleton singleton) {
synchronized (MySingleton.class) {
System.out.println(singleton);
}
}
} public class MySingletonTest {
public static void main(final String[] args) {
new Thread(() -> {
MySingleton instance = MySingleton.getInstance();
MySingleton.test(instance);
}, "t1").start();
new Thread(() -> {
MySingleton instance = MySingleton.getInstance();
MySingleton.test(instance);
}, "t2").start();
}
}Even if thread t2 obtains the reference before the constructor finishes, the synchronized test method forces the two threads to execute the print statement sequentially. By the time t2 acquires the lock, t1 has already completed object construction, so no error occurs.
Thus, synchronized guarantees serial execution of critical sections (ordering) but does not eliminate low‑level instruction reordering.
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.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
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.
