synchronized vs ReentrantLock — Which Lock to Use?
Fast recall
Quick revision
Core answer
Understanding of Java's two locking models and the practical tradeoffs between simplicity and control.
Forgetting to call lock.unlock() in a finally block with ReentrantLock, causing a permanent lock if an exception is thrown.
Mention that since Java 15 biased locking was deprecated and removed in Java 21, so the JIT advantage of synchronized has narrowed, but synchronized still wins on readability for simple critical sections.
Interview-ready guide
Interview answer
synchronized is simpler — the JVM manages lock/unlock automatically. ReentrantLock adds three capabilities that synchronized lacks.
Three reasons to use ReentrantLock:
tryLock(timeout): returns false after timeout instead of blocking indefinitely — prevents permanent waitslockInterruptibly(): throwsInterruptedExceptionfor responsive shutdown; a thread BLOCKED onsynchronizedcannot be interrupted- Multiple
Conditionobjects: producersawaitonnotFull, consumers onnotEmpty— separate wait queues, precise wakeups
What synchronized still has:
- Automatic unlock — forgetting
unlock()in afinallyblock with ReentrantLock is a permanent deadlock - Slightly more concise syntax for simple cases
- JVM can apply lock elision and bias optimization transparently
Both are reentrant:
- A thread holding the lock can re-acquire it without deadlocking
- ReentrantLock also offers a fairness option for FIFO ordering — avoid it for performance unless starvation is observed
I recommend synchronized for simple critical sections and ReentrantLock only when you need timeout, interruptibility, or multiple conditions.
synchronized vs ReentrantLock — Which Lock to Use
Direct Answer
synchronized is the simpler, JVM-managed lock that automatically releases on scope exit and benefits from JIT optimisations like biased locking. ReentrantLock provides explicit control: interruptible acquisition, timed tryLock, multiple Condition variables, and fairness policies. Choose ReentrantLock when you need any of those advanced features; otherwise prefer synchronized for its clarity and safety.
Deep Dive & Architecture
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).
synchronized is the simpler, JVM-managed lock that automatically releases on scope exit and benefits from JIT optimisations like biased locking. ReentrantLock provides explicit control: interruptible acquisition, timed tryLock, multiple Condition variables, and fairness policies. Choose ReentrantLock when you need any of those advanced features; otherwise prefer synchronized for its clarity and safety.
Mentioning only mutual exclusion. Missing the visibility / memory-model angle entirely. Confusing volatile (visibility only) with synchronized (both)
Common Mistakes & Pitfalls
Forgetting to call lock.unlock() in a finally block with ReentrantLock, causing a permanent lock if an exception is thrown.
Check your understanding
Answer these without looking back at the article.
- What is synchronization in Java? Why is it needed, and what guarantees does it provide?
- Explain how the synchronized keyword works in Java. What is a monitor, and what guarantees does synchronization provide?
- What's the difference between a synchronized method and a synchronized block in Java? When should you use each?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.