reentrantlock 通过 state 和 exclusiveownerthread 实现可重入:state 计数重入次数,exclusiveownerthread 标识持有线程;首次加锁 cas 将 state 设为1并设置 owner,重入时直接 state++,unlock 时 state--,归零才释放;公平与非公平锁在重入逻辑上完全一致。

ReentrantLock 通过内部的同步状态(state)和持有线程(exclusiveOwnerThread)两个核心字段,配合 CAS 操作实现可重入计数管理。
state 字段承担重入次数计数
ReentrantLock 基于 AQS(AbstractQueuedSynchronizer),其 state 是一个 int 类型的 volatile 变量,直接表示当前锁被同一个线程重复获取的次数:
- 初始值为 0,表示锁空闲;
- 线程首次成功加锁时,通过 CAS 将 state 从 0 设为 1;
- 同一线程再次调用 lock() 时,state 增加 1(非 CAS,因为已持有锁,无需竞争);
- 每次 unlock() 则 state 减 1;
- 当 state 减至 0,锁才真正释放,其他线程才有机会获取。
exclusiveOwnerThread 标识当前持有者
AQS 中的 exclusiveOwnerThread 字段记录当前独占锁的线程引用:
- 加锁前先检查该字段是否等于当前线程;
- 若相等,说明是重入,跳过竞争逻辑,直接 state++;
- 若为 null 或不等,则尝试 CAS 获取锁(state 从 0→1),成功后设置 exclusiveOwnerThread = 当前线程;
- unlock 时也校验:只有持有线程才能解锁,防止误释放。
非公平锁与公平锁在重入处理上一致
无论 FairSync 还是 NonfairSync,重入逻辑完全相同——都依赖 state 和 exclusiveOwnerThread 的配合。区别仅在于首次争抢锁时的行为:
- 非公平锁:插队尝试 CAS 抢锁(可能绕过队列);
- 公平锁:必须排队,按 FIFO 顺序获取;
- 但一旦进入重入路径(即 exclusiveOwnerThread 已匹配),两者都直接递增 state,不涉及队列或 CAS 竞争。
tryLock 和条件变量也遵循同一套计数规则
所有加锁方式(lock()、tryLock()、lockInterruptibly())以及 Condition.await()/signal(),底层都共享 state 和 owner 状态:
- await() 会先完全释放锁(state 归零 + owner 清空),再挂起线程;
- signal() 唤醒后,线程重新竞争锁,若原线程再次获得,state 从 0 开始累加(不是恢复之前的值);
- 也就是说,可重入性只在单次连续持有期间有效,跨 await 不保留重入深度。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











