What Is Synchronization in Java — Mutual Exclusion and Memory Visibility Explained
Fast recall
Quick revision
Core answer
ReentrantLock, StampedLock, ReadWriteLock). Synchronization is enforced through the Java Memory Model (JSR 133) via happens-before relationships.Whether the candidate knows BOTH problems synchronization solves (atomicity + visibility), not just 'preventing two threads from running the same code'
Mentioning only mutual exclusion. Missing the visibility / memory-model angle entirely. Confusing `volatile` (visibility only) with `synchronized` (both)
Mention the Java Memory Model, happens-before, that uncontended `synchronized` is optimized with biased/lightweight locking, and that modern code prefers `j.u.c.atomic` and `ReentrantLock` over raw `synchronized` for fine control
Interview-ready guide
Interview answer
Synchronization is how Java serializes access to shared mutable state.
Why it's needed — two separate problems
- Race conditions —
counter++is actually read-add-write; two threads interleaving lose updates - Memory visibility — CPUs write to per-core caches; one thread may never see another thread's write without synchronization
- Classic symptom: a
while(running)loop never exits because the other thread'srunning = falseis cached
The three guarantees `synchronized` provides
- Mutual exclusion — only one thread inside the protected section
- Memory visibility — writes inside the block are visible after another thread acquires the same lock
- Ordering — no reordering of reads or writes across the lock boundary
- These are formalized by the Java Memory Model (JSR 133) via happens-before relationships
The tool layers in Java
- `synchronized` — all three guarantees; simplest; reentrant; uninterruptible
- `volatile` — visibility only, NOT atomicity; perfect for one-writer-many-readers flags
- `java.util.concurrent.atomic` — lock-free atomics:
AtomicInteger,AtomicReference,LongAdder - `ReentrantLock` —
synchronizedon steroids:tryLock(timeout), fairness, interruptibility, multiple conditions - `StampedLock` / `ReadWriteLock` — for read-heavy workloads
- Concurrent collections —
ConcurrentHashMap,CopyOnWriteArrayList,BlockingQueue
How `synchronized` works internally
- Every Java object has a hidden mark word for monitor state
- Uncontended: lightweight lock with CAS on the mark word — tens of nanoseconds
- Under contention: inflates to an OS mutex; blocked threads park in the kernel
- Reentrant: a thread that owns the lock can enter again
- Automatically released on exception (implicit finally)
Common pitfalls
volatileon a counter — doesn't makecounter++atomic- Synchronizing on
thisor on public fields — external code can also synchronize on them, causing unexpected contention; always use a private final lock object - Large
synchronizedblocks — hold the lock longer than needed, reducing throughput - Nested locks in inconsistent order — deadlock
Recommendation: Reach for the lightest tool that fits. Flag-style visibility → volatile. Simple counters → AtomicInteger or LongAdder. Small critical sections → synchronized(privateLock) with a private final lock object. Need tryLock, fairness, or interruptibility → ReentrantLock. Shared maps/queues → concurrent collections from java.util.concurrent. Never hand-roll synchronization when a concurrent collection or atomic exists — the JDK implementations are battle-tested and much faster than what you'd build under contention.
What Is Synchronization in Java — Mutual Exclusion and Memory Visibility Explained
Direct Answer
Synchronization is how Java serializes access to shared mutable state so that concurrent code stays correct. It provides two guarantees: mutual exclusion (only one thread executes the protected section at a time) and memory visibility (writes made inside a synchronized block by one thread are visible to any thread that later acquires the same lock). Without synchronization, you get race conditions (lost updates) and visibility bugs (a thread reads stale values because the CPU cache hasn't flushed). Java provides multiple tools: the synchronized keyword (intrinsic monitor locks), volatile (visibility only, no atomicity), java.util.concurrent.atomic (lock-free atomics), and the java.util.concurrent.locks package (ReentrantLock, StampedLock, ReadWriteLock). Synchronization is enforced through the Java Memory Model (JSR 133) via happens-before relationships.
Common Mistakes & Pitfalls
Mentioning only mutual exclusion. Missing the visibility / memory-model angle entirely. Confusing volatile (visibility only) with synchronized (both)
Check your understanding
Answer these without looking back at the article.
- What's the difference between `synchronized` and `volatile`?
- Why can't `volatile` make `counter++` atomic?
- What does happens-before mean in the Java Memory Model?
- Why was biased locking deprecated in Java 15?
- When would `ReentrantLock` be a better choice than `synchronized`?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.