The volatile keyword is used for variables to ensure that changes made by one thread are immediately visible to other threads. It helps prevent caching issues in multi-threaded environments.
In Java, multiple threads may cache a variable's value locally instead of reading it from the main memory. This can cause issues where one thread modifies a variable, but another thread doesn’t see the update.
🔹 volatile forces all threads to always read/write from main memory, ensuring visibility.
- Ensures visibility of changes across threads.
- Prevents caching of variables in CPU registers or thread-local memory.
- Does NOT provide atomicity (cannot be used for operations like
count++).
class Example {
private static boolean flag = false;
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
while (!flag) { // ❌ Might be stuck in an infinite loop
}
System.out.println("Flag changed! Exiting loop...");
});
thread1.start();
Thread.sleep(2000);
flag = true; // Updated by main thread
}
}💡 Problem?
Thread1 might not see the updated flag = true because it caches the value instead of checking main memory.
class Example {
private static volatile boolean flag = false; // ✅ Ensures visibility
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
while (!flag) { // ✅ Will exit when flag is changed
}
System.out.println("Flag changed! Exiting loop...");
});
thread1.start();
Thread.sleep(2000);
flag = true; // ✅ Immediately visible to thread1
}
}✅ Now, thread1 sees the updated value immediately!
🚨 volatile does NOT ensure atomicity!
class Example {
private volatile int count = 0;
public void increment() {
count++; // ❌ Not atomic (read → modify → write)
}
}👉 Fix: Use synchronized instead:
class Example {
private int count = 0;
public synchronized void increment() { // ✅ Ensures atomicity
count++;
}
}✅ When one thread writes, and multiple threads read.
✅ For flags (e.g., boolean running = true).
✅ When avoiding caching issues in multi-threading.
❌ Do NOT use for counters (++ operations) – use synchronized or AtomicInteger instead.
volatileensures visibility, prevents caching, but does NOT ensure atomicity.- Use it for simple status flags, but not for operations like
count++. - If multiple threads modify shared data, use
synchronizedorAtomicInteger.