multi threading
intermediatesynchronized 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 guarantees13
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/retries14
* 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