Why Interviewers Prefer ReentrantLock Over synchronized: Underlying Mechanisms and Performance Gains
In ultra‑high‑concurrency scenarios, synchronized becomes a bottleneck, while ReentrantLock can boost QPS by about 30% thanks to its active AQS state management, avoidance of biased‑lock revocation, more flexible spinning, and richer APIs, and the article outlines when to choose each.
Lock Upgrade Mechanisms Comparison
synchronizedfollows a passive lock‑upgrade path (no‑lock → biased lock → lightweight lock → heavyweight lock) where each transition is triggered by contention and may involve costly CAS operations and safepoint pauses. ReentrantLock is built on AbstractQueuedSynchronizer (AQS), actively managing a volatile int state and a CLH queue, allowing immediate lightweight competition without biased‑lock steps.
Why ReentrantLock Performs Better
Assumed workload: 20 threads, each requesting the lock 100 k times per second, with lock hold time < 100 ns.
QPS: synchronized 8.5 万/s vs ReentrantLock 12.3 万/s (+44.7%).
Average latency: 117 ns vs 81 ns (‑30.8%).
CPU usage: 65 % vs 52 % (‑20%).
Key reasons:
Avoiding biased‑lock revocation : synchronized must revoke biased locks under contention, invoking biasedLocking::revoke_and_rebias and causing a safepoint pause; ReentrantLock has no such step.
More efficient spinning : non‑fair ReentrantLock lets threads “cut in line”, reducing suspend/resume overhead, whereas synchronized uses a fixed spin count (adjustable only via -XX:PreBlockSpin).
Memory layout optimization : ReentrantLock 's state is volatile and updated via compareAndSetState, enabling lock‑free reads; synchronized stores lock state and thread ID together in the object’s Mark Word, increasing memory footprint.
Production‑Environment Selection Strategy
Prefer synchronized when:
Code simplicity is critical (method‑level synchronized or block‑level synchronized(this)).
Low contention and lock hold time > 100 ns, allowing biased lock to reduce context switches.
Compatibility with wait() / notify() is required (AQS does not directly support condition variables).
Prefer ReentrantLock when:
High‑contention short‑lock scenarios such as cache‑penetration protection or rate‑limiting counters.
Advanced features are needed: fair lock, interruptible lock ( lockInterruptibly()), timed tryLock, etc.
Avoiding lock‑upgrade overhead in environments with thread counts far exceeding CPU cores (e.g., containerized deployments).
Case Study
A payment system replaced an order‑level synchronized block with ReentrantLock. TPS rose from 2000 to 3500, but developers had to ensure manual unlock in a finally block to prevent deadlocks, and they chose the non‑fair lock after observing a 15 % QPS drop with the fair mode.
Conclusion
The fundamental difference is that synchronized relies on JVM‑managed lock upgrades, while ReentrantLock actively controls state via AQS. In high‑contention short‑lock scenarios, ReentrantLock wins by avoiding biased‑lock revocation and using a more flexible spin strategy. Selection should consider contention level, lock hold time, and required advanced features rather than blindly replacing one with the other.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer1970
Formerly called 'Code to 35'. Add our main WeChat ID to access a wealth of shared resources (algorithms, interview prep, tech stacks: Java, Python, Go, big data). We mainly share serious development techniques, focusing on output-driven input. Occasionally we post life snippets and gossip. Our aim is to attract precise traffic and test advertising opportunities.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
