Definition

The volatile keyword in Java is a mechanism that helps achieve visibility of changes to variables across multiple threads. When a variable is declared volatile, it means:

  1. No caching: Threads read the value of the volatile variable directly from the main memory rather than from their thread-local cache.
  2. Happens-before guarantee: Any write to a volatile variable happens before any subsequent read of that variable.

Example

class VolatileExample extends Thread {
private volatile boolean running = true;

public void run() {
System.out.println("Thread started...");
while (running) {
// Busy-waiting for `running` to become false
}
System.out.println("Thread stopped.");
}
public void stopThread() {
running = false; // Setting running to false
}

public static void main(String[] args) throws InterruptedException {
VolatileExample thread = new VolatileExample();
thread.start(); // Start the thread
Thread.sleep(1000); // Sleep for 1 second
System.out.println("Stopping thread...");
thread.stopThread(); // Change the `running` variable to false
}
}

Output

Thread started...
Stopping thread...
Thread stopped.

Feature

  • Changes made to a volatile variable are visible to all threads immediately.
  • Ensures that reads and writes to volatile variables happen in a predictable order.
  • Unlike synchronized, volatile does not introduce locking, meaning it doesn’t block other threads but offers better performance for certain scenarios.
  • It does not guarantee that compound actions (like incrementing a value) are thread-safe.

Advantages

  • It is lighter than using synchronized blocks, as it does not involve locking.
  • Ensures that all threads have the most up-to-date value of a shared variable, preventing data inconsistency issues.
  • Useful in cases where variables are frequently read but rarely updated, providing better performance compared to locks.
  • Ideal for use-cases like status flags (running, isActive, etc.) where visibility is more critical than atomicity.