Under The Hood
backend java JDK 21+ (biased locking removed in 15, synchronized + AQS)

synchronized Monitor Inflations vs ReentrantLock (AQS)

Last updated
Prerequisites:
Java threads and synchronization basics
Understanding of locks and condition variables
  • java
  • synchronized
  • reentrantlock
  • aqs
  • monitor
  • locking
  • concurrency

Read at your depth

The practical view

synchronized blocks/methods use intrinsic monitors: automatic, concise, and reentrant (the same thread can re-acquire). ReentrantLock offers more: tryLock(timeout), lockInterruptibly(), fair locking, and Condition objects (await/signal instead of wait/notify). Both are reentrant. Performance is similar in modern JVMs; choose synchronized for simplicity and ReentrantLock when you need timeout/try-lock/interruptibility/fairness/multiple conditions. Always release ReentrantLock in finally (unlock), whereas synchronized releases automatically.

The same idea in other frameworks

react equivalent
N/A — JVM concurrency concern.

Legacy vs modern

synchronized timeout problem vs ReentrantLock tryLock

synchronized cannot time out or be interrupted while waiting; ReentrantLock.tryLock(timeout) gives bounded waits, but requires manual unlock.

before → after
synchronized — no timeout, no interrupt
synchronized (lock) {
  // ❌ OLD: if another thread holds the lock forever, this blocks forever
}
ReentrantLock.tryLock with timeout
if (lock.tryLock(2, TimeUnit.SECONDS)) { try { ... } finally { lock.unlock(); } } // ✅ NEW

Interview gotchas

Context

This tests the monitor mechanics — interviewers want the thin-lock → heavyweight transition and why uncontended synchronized is cheap, not just 'synchronized uses the monitor'.

The mechanical answer

An uncontended synchronized block performs a thin-lock fast path: a single CAS on the object header's mark word, typically by the interpreter/JIT with no OS involvement — very cheap. When contention occurs (another thread tries to acquire), the lock 'inflates' to a heavyweight ObjectMonitor: the mark word is replaced with a pointer to the monitor structure, which manages an owner field, entry queues (cxq/EntryList), and a wait set for wait/notify. Inflated monitors park blocked threads via the OS (LockSupport/mutex), which is expensive. Since JDK 15, biased locking is removed, so there is no biased-lock acquisition; the fast path is thin-lock CAS, and the slow path is the inflated monitor. This design is why synchronized scales well when uncontended and degrades under heavy contention like any parking-based lock.

Trap

The naive answer is 'synchronized is always heavyweight'. It's thin until contention inflates it. Another trap: assuming synchronized and ReentrantLock have identical semantics — both are reentrant, but ReentrantLock adds timeout/interrupt/fairness/conditions, and synchronized's wait/notify requires holding the monitor (with spurious-wakeup caveats). Candidates who describe the mark word and inflation path show real JVM understanding.

Under The Hood — a multi-depth technical interview hub.

Third-party licenses Press ⌘ K to search.