Understanding AQS and ReentrantLock Implementation in Java

AbstractQueuedSynchronizer (AQS) Overview

AQS serves as a framework for blocking locks and synchronizer utilities. Key characteristics include:

  1. State Management: Uses state (32-bit int) to represent resource status (exclusive/shared mode)
  2. FIFO Queue: Maintains a wait queue for blocked threads
  3. Condition Variables: Supports multipel condition variables for signaling

Core Methods to Implement

protected boolean tryAcquire(int arg)
protected boolean tryRelease(int arg)
protected int tryAcquireShared(int arg)
protected boolean tryReleaseShared(int arg)
protected boolean isHeldExclusively()

Custom Lock Implemantation Example

class CustomLock implements Lock {
    private final Sync sync = new Sync();
    
    static class Sync extends AbstractQueuedSynchronizer {
        protected boolean tryAcquire(int acquires) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }
        
        protected boolean tryRelease(int releases) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }
    }
    
    // Lock interface methods implementation
    public void lock() { sync.acquire(1); }
    public void unlock() { sync.release(1); }
    // ... other methods
}

ReentrantLock Implementation

Nonfair Lock Mechanics

Lock Acquisition:

  1. Direct CAS attempt on state (0→1)
  2. On failure, anqueue thread via acquire()
final void lock() {
    if (compareAndSetState(0, 1))
        setExclusiveOwnerThread(Thread.currentThread());
    else
        acquire(1);
}

Lock Release:

  1. Sets state = 0 and owner = null
  2. Unparks successor thread from queue

Reentrancy Mechanism

protected final boolean tryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        // Initial acquisition
    } 
    else if (current == getExclusiveOwnerThread()) {
        // Reentrant acquisition
        setState(c + acquires);
        return true;
    }
    return false;
}

Fair vs Nonfair Locks

Key Difference: Fair locks check queue before acquisition

protected final boolean tryAcquire(int acquires) {
    if (!hasQueuedPredecessors() && 
        compareAndSetState(0, acquires)) {
        setExclusiveOwnerThread(current);
        return true;
    }
    // ...
}

Condition Variables

Await Process:

  1. Adds node to condition queue
  2. Fully releases lock
  3. Parks thread

Signal Process:

  1. Transfers node from condition queue to sync queue
  2. Unparks thread when lock becomes available
public final void await() throws InterruptedException {
    Node node = addConditionWaiter();
    int savedState = fullyRelease(node);
    while (!isOnSyncQueue(node)) {
        LockSupport.park(this);
    }
    // ...
}

Tags: java Concurrency AQS ReentrantLock Synchronization

Posted on Thu, 17 Sep 2026 16:05:15 +0000 by timetomove