state 在 ReentrantLock 中的精确含义与核心作用
在 ReentrantLock 的底层实现中,AQS 的 state 字段并非简单的“有锁/无锁”二元标记,而是精确记录当前持有锁的线程重复加锁的次数。换句话说,它直接承载了“可重入次数”这一核心语义,是 Java 并发锁机制中判断锁重入状态的关键变量。

state 是可重入锁逻辑的核心依据
ReentrantLock 允许同一线程多次调用 lock() 而不阻塞,靠的就是 state 的累加计数机制。具体来说:
- 首次获取锁时,通过 CAS 操作将 state 从 0 改为 1,同时把当前线程记录为独占线程(
exclusiveOwnerThread) - 同一线程再次调用
lock(),发现当前线程就是持有者,就直接让 state +1(比如变成 2、3……),实现嵌套重入 - 每次
unlock()都使 state -1;只有当 state 减到 0 时,才算真正释放锁,并清空独占线程引用
这个递增递减机制保证了同一个线程可以嵌套加锁而不会自己将自己阻塞,是 ReentrantLock 实现线程内部重入功能的基础。
state 和线程归属必须严格匹配才能正确判断重入
重入判断并不只看 state > 0,而是通过双重校验完成:
- 先检查
exclusiveOwnerThread == Thread.currentThread(),确认当前线程是否为锁的持有者 - 再决定是走重入分支(state++),还是走竞争分支(入队等待)
- 如果 state > 0 但线程不匹配,说明锁被其他线程持有,当前线程只能进入等待队列排队
换句话说,state 本身并不包含线程信息,必须结合 exclusiveOwnerThread 才能正确区分重入与外部竞争。这正是 AQS 框架设计精妙之处:将“锁归属”与“持有计数”分离,让 state 保持纯粹的数值语义,同时用额外字段记录所有权,使得整个锁状态的管理既简洁又严谨。
公平性模式不影响 state 含义,只影响锁获取时机
无论公平锁还是非公平锁,state 始终表示“当前线程的可重入持有次数”。区别仅在于尝试获取锁的策略不同:
- 非公平模式:先尝试抢夺(通过 CAS 修改 state),抢不到再检查等待队列
- 公平模式:先调用
hasQueuedPredecessors(),若队列非空则直接放弃抢锁,按顺序排队 - state 本身的语义和更新逻辑在两种模式下完全一致,不受公平性设定影响
因此,公平性只是锁获取入口策略的差异,并不改变 state 作为重入次数计数器的本质特征。
对比其他 AQS 同步器,state 含义各不相同
同一套 AQS 框架下,不同同步器对 state 字段的解释完全不同——这正是 AQS 高度灵活性的体现:
- ReentrantLock:state = 当前线程的重入次数(独占锁嵌套深度)
- Semaphore:state = 剩余可用许可数(不绑定任何特定线程)
- CountDownLatch:state = 当前倒计数值(用于等待其他线程完成)
- ReentrantReadWriteLock:state 高 16 位表示读锁持有总数,低 16 位表示写锁重入次数
可以看到,AQS 提供了一个“原子整数 + 等待队列”的通用骨架,而具体如何解读 state 完全由子类自行定义。ReentrantLock 选择用它来记录“锁的嵌套深度”,这一设计既简洁又高效,完美支撑了可重入独占锁的语义需求。
