How Java’s AQS Powers ReentrantLock – A Deep Dive into the Source
This article explains the core concepts of Java’s AbstractQueuedSynchronizer (AQS), its exclusive and shared modes, the template‑method design it uses, and walks through the actual source code showing how ReentrantLock implements both fair and non‑fair locking, complete with diagrams and code snippets for interview preparation.
AQS Overview
AbstractQueuedSynchronizer (AQS) is the backbone of the Java java.util.concurrent package. It provides a framework for building locks and synchronizers such as ReentrantLock, ReentrantReadWriteLock, Semaphore, CountDownLatch and CyclicBarrier. AQS manages a volatile state field that represents the lock’s acquisition status and a double‑linked CLH queue that orders waiting threads.
Acquisition Modes
AQS supports two acquisition modes:
Exclusive mode : only one thread can hold the resource at a time (e.g., ReentrantLock).
Shared mode : multiple threads may hold the resource simultaneously, up to a configurable limit (e.g., Semaphore, CountDownLatch).
Key AQS Methods
// exclusive mode
public final void acquire(int arg)
public final void acquireInterruptibly(int arg)
public final boolean tryAcquireNanos(int arg, long nanosTimeout)
public final boolean release(int arg) // shared mode
public final void acquireShared(int arg)
public final void acquireSharedInterruptibly(int arg)
public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
public final boolean releaseShared(int arg)Subclasses must implement the following abstract methods, which AQS calls from its template methods:
protected abstract boolean tryAcquire(int arg);
protected abstract boolean tryRelease(int arg);
protected abstract int tryAcquireShared(int arg);
protected abstract boolean tryReleaseShared(int arg);
protected abstract boolean isHeldExclusively();This design follows the template method pattern : the abstract class defines the algorithm’s skeleton while concrete subclasses provide the specific steps.
ReentrantLock Implementation
Inside ReentrantLock there is a static inner class Sync that extends AbstractQueuedSynchronizer. Two concrete subclasses, FairSync and NonfairSync, implement the fair and non‑fair locking policies.
Non‑fair Lock Logic
The non‑fair lock first tries to acquire the lock without queuing:
final boolean initialTryLock() {
Thread current = Thread.currentThread();
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(current);
return true;
} else if (getExclusiveOwnerThread() == current) {
int c = getState() + 1;
if (c < 0) throw new Error("Maximum lock count exceeded");
setState(c);
return true;
} else {
return false;
}
}If this fast path fails, acquire(1) is invoked, which delegates to tryAcquire and, on failure, enqueues the thread in the CLH queue.
protected final boolean tryAcquire(int acquires) {
if (getState() == 0 && compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}The enqueue‑and‑park logic is handled by the private method acquire(null, arg, false, false, false, 0L). It creates a node, links it at the tail of the queue, and then repeatedly checks the predecessor’s status, spins for a short time, and finally calls LockSupport.park() to block the thread until it is unparked by the releasing thread.
UML Diagram
Design Insights
The AQS implementation showcases high code reuse: the abstract class supplies most of the synchronization logic, while concrete synchronizers only need to define how to acquire and release the resource. This separation also makes the framework flexible for future extensions.
Understanding the template‑method pattern used by AQS helps developers see why the same algorithmic skeleton can serve many different synchronizers without duplication.
Practical Takeaway for Interviews
When faced with interview questions about AQS, it is sufficient to grasp the high‑level workflow: fast‑path acquisition, fallback to queueing, state management via volatile int state, and the role of the CLH queue. Deeply memorising every line of source code is unnecessary unless the position specifically requires it.
Senior Tony
Former senior tech manager at Meituan, ex‑tech director at New Oriental, with experience at JD.com and Qunar; specializes in Java interview coaching and regularly shares hardcore technical content. Runs a video channel of the same name.
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.
