</>

Technology

Core Java

Difficulty

Advanced

Interview Question

What is the difference between volatile and synchronized in Java?

Answer

volatile vs synchronized in Java

Both deal with multi-threading, but solve different problems.

volatile Keyword

  • Guarantees visibility — changes to a volatile variable are immediately visible to all threads
  • Does NOT guarantee atomicity — compound operations (i++) are not thread-safe with volatile
  • No locking — threads do NOT block
Java
public class Counter {
    private volatile boolean running = true;  // visible to all threads immediately
    private volatile int    count    = 0;     // reads/writes are atomic for primitives

    public void stop() {
        running = false;  // immediately visible to other threads
    }

    public void run() {
        while (running) {  // sees latest value of running
            // do work
        }
    }
}

volatile is Enough When:

  • You have a flag (boolean) that one thread writes and others read
  • Variable is read/written independently (not compound operation)
Java
// CORRECT: single write, multiple reads — volatile is sufficient
private volatile boolean shutdownRequested = false;

public void shutdown()  { shutdownRequested = true; }
public boolean isDone() { return shutdownRequested; }

synchronized Keyword

  • Guarantees both visibility AND atomicity (mutual exclusion)
  • Only one thread enters a synchronized block at a time
  • Other threads block and wait
Java
public class SafeCounter {
    private int count = 0;

    // synchronized — only one thread increments at a time
    public synchronized void increment() {
        count++;  // read + increment + write = compound operation — needs sync
    }

    public synchronized int getCount() {
        return count;
    }
}

Why volatile is NOT Enough for count++

Java
// count++ is NOT atomic — it's three operations:
// 1. read current value of count
// 2. add 1
// 3. write back the new value

// Two threads can read 5 simultaneously, both write 6 → count = 6 instead of 7!
private volatile int count = 0;  // ⚠️ still broken for count++

Direct Comparison

Featurevolatilesynchronized
VisibilityYesYes
AtomicityNoYes
PerformanceFast (no locking)Slower (blocks)
Use forFlags, statusCounters, compound actions
Blocks threadsNoYes

Better Alternatives — java.util.concurrent.atomic

Java
// AtomicInteger — atomic operations without explicit locking
private AtomicInteger count = new AtomicInteger(0);

public void increment() {
    count.incrementAndGet();  // atomic: read + increment + write
}

public int getCount() {
    return count.get();
}

// Other atomic operations
count.compareAndSet(expected, newValue);
count.addAndGet(delta);
count.getAndSet(newValue);

Practical Example

Java
public class SharedState {
    // volatile — flag that signals all threads to stop
    private volatile boolean stopRequested = false;

    // synchronized — compound operation on shared counter
    private int taskCount = 0;
    private final Object lock = new Object();

    public void requestStop() {
        stopRequested = true;  // volatile write — all threads see immediately
    }

    public boolean isStopRequested() {
        return stopRequested;  // volatile read
    }

    public void incrementTaskCount() {
        synchronized (lock) {
            taskCount++;  // compound — needs synchronization
        }
    }

    public int getTaskCount() {
        synchronized (lock) {
            return taskCount;
        }
    }
}

Follow AutomateQA

Related Topics