state变量是ReentrantLock的核心状态载体,承担锁空闲/持有标识与重入计数双重职责:state==0表示锁空闲,可被任意线程CAS获取;state>0表示同一线程重入次数,仅当state减至0才真正释放锁并唤醒等待线程;其volatile语义与CAS保障跨线程可见性与原子性。

state 变量在 ReentrantLock 中直接承担锁状态标识与重入次数计数双重职责,不是辅助字段,而是核心状态载体——它不记录“哪个线程持有”,只精确表达“被同一个线程持有了几次”。
state == 0 表示锁完全空闲
此时没有线程持有锁,任何线程调用 lock() 都可尝试通过 CAS 将 state 从 0 改为 1。一旦成功,AQS 同时设置 exclusiveOwnerThread = currentThread,完成首次加锁绑定。
state > 0 代表当前线程的重入深度
- 值为 1:线程首次获取锁
- 值为 2:同一线程已 lock() 两次,尚未 unlock() 一次
- 值为 n:该线程已成功获取锁 n 次,还需调用 unlock() n 次才能真正释放
每次重入时,tryAcquire 先比对 getExclusiveOwnerThread() == currentThread,成立则直接执行 setState(state + 1),跳过竞争逻辑。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
state 减至 0 才触发锁释放与唤醒
每次 unlock() 都执行 setState(state - 1):
立即学习“Java免费学习笔记(深入)”;
- state 仍大于 0:仅递减计数,锁继续由当前线程持有,不唤醒队列中其他线程
- state 变为 0:表示锁彻底释放,AQS 清除
exclusiveOwnerThread,并唤醒同步队列头部节点
为什么必须用 volatile int state,而不是 ThreadLocal?
因为锁的释放判定(state == 0)必须对所有线程可见且可参与原子竞争:
- ThreadLocal 值仅本线程可见,其他线程无法感知其变化,无法安全决定“何时唤醒”
- 若仅靠 ThreadLocal 记录重入数,线程异常中断或未正确 unlock,会导致本地计数残留,而实际锁已丢失,引发死锁
- state 的 volatile 语义+CAS 更新,确保读写具备内存可见性与操作原子性,是跨线程协作的基础

















