ReviseAlgo Logo

Multithreading

volatile Keyword

Understand CPU caches, memory visibility, instruction reordering, and the volatile keyword.

Interview: Commonly tested on the distinction between memory visibility and atomicity, and when volatile is/isn't sufficient.

Last Updated: June 13, 2026 10 min read

In a multi-core processor, each core has its own local memory cache. The volatile keyword guarantees that modifications to a variable are immediately visible to all threads, preventing memory visibility issues.

Core Idea

Volatile forces reads/writes of a variable to go directly to main memory, bypassing CPU local caches.

Why It Matters

Without volatile, a thread might check a termination flag cached in its core and run forever, missing the shutdown call.

Interview Lens

Expect questions on why volatile does not make compound operations (like count++) thread-safe.

Visibility vs. Atomicity

It is critical to distinguish between these two concepts:

  • Visibility: Ensures changes made by one thread to a variable are visible to other threads. volatile guarantees visibility.
  • Atomicity: Ensures a set of actions executes as a single, indivisible step. volatile does NOT provide atomicity. For example, volatileCount++ is still not thread-safe.
  • Instruction Reordering: The compiler and CPU reorder instructions to optimize execution. volatile establishes a happens-before relationship, preventing reordering around volatile reads/writes.

Code Walkthrough

The following example demonstrates a thread shutdown coordinator using a volatile flag.

public class VolatileFlagDemo {
    private static volatile boolean keepRunning = true;

public static void main(String[] args) throws InterruptedException { Thread worker = new Thread(() -> { long count = 0; while (keepRunning) { count++; } System.out.println("Worker stopped. Counted: " + count); });

worker.start(); Thread.sleep(1000); // Let worker run for a second

System.out.println("Signaling stop..."); keepRunning = false; // Directly modifies main memory worker.join(); } }

Interview-Relevant Information

Q: When is it safe to use volatile instead of synchronized/locks?
Answer: You can use volatile only when: 1. The write operation does not depend on the variable's current value (e.g. flag checks, status switches). 2. The variable does not participate in invariants with other state variables. If writes depend on reads (like increments), you must use locks or atomic classes.

Quick Checklist

Does volatile guarantee atomicity? Why can CPU caches hide variable changes? What is instruction reordering? If yes, you understand the volatile keyword.

Use Cases

Shutdown flags and heartbeat loops inside worker threads.

Double-checked locking implementation of thread-safe singletons (requires volatile to prevent partial object construction reordering).

Common Mistakes

Using volatile to protect counters or shared accumulators, leading to race conditions and lost updates.

Thinking volatile variables block execution (they are completely non-blocking).