Understanding the volatile Keyword in Java Concurrency
This article explains the Java volatile keyword, covering its underlying principles, effects on visibility and instruction reordering, appropriate usage scenarios, limitations, and provides a practical code example demonstrating how volatile ensures thread visibility and prevents dead loops in multithreaded programs.
1. Principle of volatile keyword
volatile keyword is mainly used to guarantee variable visibility in a multithreaded environment and to prevent instruction reordering.
When a variable is declared volatile, threads read its value directly from main memory rather than from a local cache.
Similarly, when a thread modifies a volatile variable, the change is immediately written back to main memory.
2. Effects of volatile keyword
Ensures visibility : In a multithreaded environment, if one thread changes a volatile variable, other threads see the change immediately, avoiding data inconsistency.
Prevents instruction reordering : volatile prevents the compiler and processor from reordering code, ensuring instructions execute in program order.
3. Correct usage of volatile
Applicable scenarios : Variables accessed by multiple threads that do not involve compound operations (e.g., increment). Typical uses include status flags and control variables.
Inapplicable scenarios : Do not use volatile for operations requiring atomicity; use locks or atomic classes instead.
4. Example code
public class VolatileExample {
private volatile boolean flag = false;
public void startTask() {
// Start a thread to modify flag
new Thread(() -> {
try {
Thread.sleep(1000); // simulate time‑consuming work
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = true;
System.out.println("Flag has been set to true.");
}).start();
}
public void monitorTask() {
// Start a thread to monitor flag
new Thread(() -> {
while (!flag) {
// loop until flag becomes true
}
System.out.println("Flag is now true. Task can proceed.");
}).start();
}
public static void main(String[] args) {
VolatileExample example = new VolatileExample();
example.startTask();
example.monitorTask();
}
}In this example, one thread sets flag to true while another monitors it; without volatile, the monitoring thread might never see the update and could loop indefinitely, but volatile guarantees visibility.
Practical application
In real projects, developers often prefer the atomic classes in java.util.concurrent.atomic (e.g., AtomicInteger, AtomicBoolean) for lock‑free thread safety. These classes rely on CAS (Compare‑and‑Swap) implemented via Unsafe , but CAS alone does not solve visibility, which is why volatile remains essential.
Combining CAS for atomicity and volatile for visibility provides an efficient, lock‑free concurrency solution.
Conclusion
Typically, developers use atomic classes to ensure thread safety rather than directly using volatile , yet understanding volatile helps explain why atomic classes work and highlights its role in guaranteeing visibility.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
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.