Mastering Java Locks: When to Use synchronized vs ReentrantLock
This article explains how Java locks solve concurrent access problems, compares the built‑in synchronized lock with ReentrantLock, describes their upgrade mechanisms, usage patterns, and scenarios, and offers guidance on choosing the appropriate lock for different environments.
Preface: When I first saw the title I felt it was both familiar and unfamiliar, because locks are an effective way to guarantee atomic operations on critical resources in concurrent situations. Below we discuss the locks we commonly use as developers.
What problems can locks solve?
Locks address scenarios where multiple threads need sequential access or modification of shared data, such as parallel deductions or transfers on the same account. We will discuss synchronized, ReentrantLock, and their usage.
synchronized
synchronized is a built‑in lock provided by the JDK, implemented by the JVM based on the monitor mechanism. After JDK 1.6 it was optimized and includes a lock‑upgrade process that stores lock state in the object header.
The upgrade process starts with no lock, then checks for contention. If there is none, a biased lock is used, which records the owning thread ID in the object header. It then upgrades to a lightweight lock, implemented via CAS modifying the MarkWord. Finally it may upgrade to a heavyweight lock, which relies on the operating system's mutex.
Four usage ways
Use on static methods
Use on ordinary methods
Lock the this object
Lock a static class
Lock state record location
When an object is locked, the lock information is recorded in the object header, as shown in the diagram below.
During runtime, the data stored in the MarkWord changes as the lock flag changes. The MarkWord can store four different kinds of data, illustrated in the next diagram.
Lock inflation and upgrade
The inflation and upgrade of a lock are irreversible.
Usage scenarios
In the JDK concurrency package, synchronized is used in places such as:
ConcurrentHashMap (JDK 1.8)
Hashtable
ReentrantLock
ReentrantLockwas added to the JDK starting from version 1.5, authored by Doug Lea. It implements locking via the AQS framework, using CAS operations provided by the Unsafe package to compete for the lock state, and employs LockSupport.park to block threads until they are awakened. ReentrantLock comes in fair and non‑fair variants; the default is non‑fair because fair locks enforce acquisition order at the cost of performance.
The AQS queue structure is a FIFO thread‑safe synchronization queue, as shown below.
The lock and unlock process of ReentrantLock is illustrated in the following diagram.
Usage method
Using ReentrantLock involves three steps: create, lock, and unlock.
class X {
private final ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock();
}
}
}Usage scenarios
ReentrantLock is used in many JDK concurrency utilities, including:
CyclicBarrier
DelayQueue
LinkedBlockingDeque
ThreadPoolExecutor
ReentrantReadWriteLock
StampedLock
ReentrantLock is a fundamental class in the concurrency package and serves as a basis for learning concurrent programming.
How to choose a lock?
In a single‑machine environment, use synchronized (built‑in lock) or ReentrantLock for concurrency control.
For atomic counters, use atomic classes provided by Unsafe, such as AtomicInteger and AtomicLong.
For database operations like deducting user balances, use optimistic locking with SQL like:
update table_name set amount = 100, version = version + 1 where id = 1 and version = 1;In distributed scenarios, ensure consistency with distributed locks implemented via Redis or ZooKeeper.
Reference information
"深入理解 Java 虚拟机" by 周志明
https://blog.csdn.net/wangbo199308/article/details/108688109
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.
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
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.
