multi threading
intermediate

synchronized vs volatile

Pick the minimal tool — mutual exclusion (synchronized) vs visibility-only (volatile) — for the concurrency problem you actually have.

These two keywords are compared constantly and solve different halves of the same problem. volatile is about visibility; synchronized is about visibility and atomicity. Once you say that sentence, most follow-ups answer themselves.

volatile = posting an update on a public board (everyone sees the latest, but two people can still post conflicting updates). synchronized = the single key to a room (only one person inside, others wait).

Key Concepts

1
The problem both address. Each thread may cache values in registers or a core's cache, and the compiler may reorder instructions that look independent. A write by one thread is not automatically visible to another, and without a rule about ordering, a reader can observe events in an order that never happened from the writer's perspective.
2
volatile guarantees that every read sees the most recent write, and it forbids the reordering of surrounding operations across the access. What it does not give you is atomicity of compound actions. count++ on a volatile field is read, add, write — three steps — and two threads can interleave so that one increment is lost. This is the single most common misuse.
volatilecount++
3
synchronized gives mutual exclusion plus the same visibility guarantee. Entering a monitor invalidates the thread's cached values, and exiting flushes writes, so the lock provides a happens-before edge between the thread that releases it and the next to acquire it. It costs more than volatile — an uncontended lock is cheap thanks to biased and thin locking, but a contended one parks threads and involves the OS scheduler.
synchronizedvolatile
4
The canonical correct use of volatile is a flag. A volatile boolean running that one thread sets and another polls is exactly the case it was designed for: a single write, a single read, no compound action. Without volatile, the reading thread may hoist the check out of the loop and spin forever.
volatilevolatile boolean running
5
Double-checked locking is the classic exam question. Checking a field, taking a lock, checking again, then assigning — without volatile on the field, another thread can observe a non-null reference to an object whose constructor has not finished, because the assignment can be reordered ahead of the initialisation. With volatile, that reordering is forbidden and the idiom is correct.
volatile
6
Prefer the tools above both. AtomicInteger gives lock-free atomic compound operations via compare-and-swap. ConcurrentHashMap handles the map case. java.util.concurrent locks add try-lock, timeouts and fairness that synchronized cannot express. Reaching for these first is usually the better answer, and saying so shows judgement rather than recall.
AtomicIntegerConcurrentHashMapjava.util.concurrentsynchronized
7
What the interviewer is probing.1. "Difference between volatile and synchronized?" Probing: the visibility/atomicity split. Stalls: "volatile is lighter." Moves up: visibility only versus visibility plus mutual exclusion, with the compound-action example.
8
2. "Is volatile count++ thread-safe?" Probing: the most common misconception. Stalls: "Yes, volatile makes it atomic." Moves up: no — read-modify-write is three steps; use AtomicInteger or a lock.
volatile count++AtomicInteger
9
3. "Why does double-checked locking need volatile?" Probing: reordering, not caching. Stalls: "For visibility." Moves up: the constructor can be reordered after the reference assignment, so another thread sees a partially built object.
10
4. "When is volatile enough?" Probing: whether you can name the shape. Stalls: "For simple variables." Moves up: one writer, independent reads, no compound action — a status flag is the textbook case.
11
5. "What does synchronized cost?" Probing: calibration. Stalls: "It's slow." Moves up: uncontended locks are close to free; contention is what costs, because threads park and the scheduler gets involved.
12
  What each guarantees
13
                          volatile      synchronized   AtomicInteger
  ------------------------------------------------------------------
  Visibility of writes       yes            yes             yes
  Prevents reordering        yes            yes             yes
  Atomic read-modify-write   NO             yes             yes
  Mutual exclusion           no             yes             no (CAS)
  Blocks other threads       no             yes             no (spins)
  Usable on a 64-bit field   yes*           yes             yes
  Cost when uncontended      ~free          very low        very low
  Cost when contended        n/a            parks threads   spins/retries
14
  * long and double writes are not atomic without volatile on a
    32-bit JVM; volatile makes them so.
15
  The decision
    single flag, one writer                 -> volatile
    counter or accumulator                  -> AtomicInteger/LongAdder
    several fields that must change together-> synchronized or a Lock
    map                                     -> ConcurrentHashMap