ReentrantLock基于AQS框架的核心工作机制

深度解析AbstractQueuedSynchronizer的实现原理与应用场景

AQS核心机制

0

同步状态 (state)

使用volatile修饰,通过CAS原子操作控制状态转换

CLH

CLH变体队列

虚拟双向队列,管理等待线程的排队与唤醒

TMP

模板方法模式

子类实现具体策略,父类处理通用逻辑

ReentrantLock类结构

public class ReentrantLock implements Lock {
    private final Sync sync;  // 核心同步器

    abstract static class Sync extends AQS {
        abstract boolean initialTryLock();
        final void lock() { ... }
        protected final boolean tryRelease(int releases) { ... }
    }

    static final class NonfairSync extends Sync { ... }  // 非公平锁
    static final class FairSync extends Sync { ... }    // 公平锁
}

公平锁 vs 非公平锁性能对比

测试环境:JDK 17 | AMD R7-8745H | 32GB RAM | Ubuntu 24.04.3
测试工具:JMH 1.37 | 预热3轮×1秒 | 测试5轮×2秒 | 分叉2次
测试场景:低并发(1线程)、中并发(4线程)、高并发(16线程)

线程入队机制

Thread 1

获取锁失败

Node 1

封装为Node节点

Head
Node 1
Node 2
Tail
private Node addWaiter(Node mode) {
    Node node = new Node(Thread.currentThread(), mode);
    Node pred = tail;
    if (pred != null) {
        node.prev = pred;
        if (compareAndSetTail(pred, node)) {
            pred.next = node;
            return node;
        }
    }
    enq(node);  // 自旋入队
    return node;
}
private Node enq(final Node node) {
    for (;;) {
        Node t = tail;
        if (t == null) {  // 初始化队列
            if (compareAndSetHead(new Node()))
                tail = head;
        } else {
            node.prev = t;
            if (compareAndSetTail(t, node)) {
                t.next = node;
                return t;
            }
        }
    }
}

阻塞与自旋流程

final boolean acquireQueued(final Node node, int arg) {
    boolean failed = true;
    try {
        boolean interrupted = false;
        for (;;) {
            final Node p = node.predecessor();
            if (p == head && tryAcquire(arg)) {
                setHead(node);  // 成为新头节点
                p.next = null;  // 帮助GC
                failed = false;
                return interrupted;
            }
            // 判断是否应该阻塞
            if (shouldParkAfterFailedAcquire(p, node) && 
                parkAndCheckInterrupt()) {
                interrupted = true;
            }
        }
    } finally {
        if (failed)
            cancelAcquire(node);  // 取消获取
    }
}

Node状态流转

初始状态 (0)

节点创建时的默认状态

SIGNAL (-1)

后继节点需要被唤醒

CANCELLED (1)

线程已取消等待

CONDITION (-2)

在条件队列中等待

PROPAGATE (-3)

共享模式下的唤醒传播

释放锁与唤醒流程

tryRelease释放逻辑

protected final boolean tryRelease(int releases) {
    int c = getState() - releases;
    if (getExclusiveOwnerThread() != Thread.currentThread())
        throw new IllegalMonitorStateException();
    boolean free = (c == 0);
    if (free)
        setExclusiveOwnerThread(null);  // 清空持有者
    setState(c);  // 更新状态
    return free;  // 是否完全释放
}

unparkSuccessor唤醒机制

private void unparkSuccessor(Node node) {
    int ws = node.waitStatus;
    if (ws < 0)
        compareAndSetWaitStatus(node, ws, 0);
    
    Node s = node.next;
    if (s == null || s.waitStatus > 0) {
        s = null;
        // 从队尾向前遍历寻找有效节点
        for (Node t = tail; t != null && t != node; t = t.prev)
            if (t.waitStatus <= 0)
                s = t;
    }
    if (s != null)
        LockSupport.unpark(s.thread);  // 唤醒线程
}

性能优化策略

自适应自旋

根据等待时间动态调整自旋次数,减少上下文切换开销

懒清理机制

延迟清理CANCELLED状态节点,避免频繁的链表操作

后向遍历唤醒

从队尾向前遍历寻找有效节点,保证指针一致性

AQS同步器对比

同步器 模式 state含义 特点
ReentrantLock 独占 重入次数 可重入,支持公平/非公平
Semaphore 共享 许可证数量 控制并发访问数量
CountDownLatch 共享 计数器 一次性屏障,不可重置