ReentrantReadWriteLock 的写锁重入是安全且被明确设计支持的,基于 AQS 实现,重入计数存于 state 低 16 位,由 CAS 原子操作维护;重入期间读锁被完全阻塞,支持降级但禁止升级,非公平/公平模式下重入均不参与队列竞争。

ReentrantReadWriteLock 的写锁重入是安全的,且被明确设计为支持同一线程多次获取写锁。
写锁重入机制本身是线程安全的
写锁基于 AQS 实现,其重入计数保存在 state 变量的低 16 位(即 exclusive count)。每次同一线程调用 writeLock().lock(),AQS 会原子性地增加该计数;unlock() 则递减。整个过程由 CAS 操作保障,不存在竞态条件。
- 底层通过
exclusiveCount(state)提取写锁持有次数,逻辑为:state & 0xFFFF - 判断是否为当前线程持有:AQS 内部维护
Thread exclusiveOwnerThread字段,仅当匹配时才允许重入 - 重入上限为 65535(
2^16 - 1),超限会抛出Error,但正常业务极少触及
重入期间读锁被完全阻塞
只要写锁被任意线程持有一份(无论是否重入),所有读锁请求都会被拒绝——包括持有写锁的线程自己发起的新读锁请求(除非主动降级)。
- 这是“读写互斥”规则的刚性体现,不是 bug,而是设计约束
- 避免了“读锁插在写锁重入中间”导致的数据不一致风险
- 例如:线程 T 持有写锁 2 次,此时其他线程调用 readLock().lock() 会阻塞,T 自己也不能直接 acquire 读锁(需先释放写锁或走降级路径)
可降级但不可升级,保障重入语义清晰
写锁重入后,若需切换为读状态,必须显式执行“锁降级”:在仍持有写锁的前提下获取读锁,再释放写锁。这个过程是原子且受控的。
立即学习“Java免费学习笔记(深入)”;
- 降级安全:AQS 确保降级过程中不会被其他线程抢占写权限
- 禁止升级:持有读锁的线程不能 later 获取写锁,防止因等待写锁而造成死锁(尤其在重入嵌套场景下)
- 因此,写锁重入始终处于独占、可控、可预测的状态,不依赖外部同步逻辑
非公平模式下重入仍保持一致性
默认非公平模式允许新线程“插队”,但这不影响已持有写锁线程的重入行为——它的后续 lock() 调用总是成功,无需排队,也不受其他线程插队影响。
- 因为重入判定发生在锁持有者本地,不参与 CLH 队列竞争
- 插队只影响尚未获得锁的线程,对已进入重入路径的线程透明
- 公平模式下也同理,只是新请求按 FIFO 排队,重入本身不排队


















