ReentrantReadWriteLock非公平模式不保证写锁优先,仅允许新线程插队竞争;写饥饿源于读线程持续抢占,需用公平模式、信号量限流或StampedLock缓解。

ReentrantReadWriteLock 在非公平模式下 并不保证写锁优先,也不会主动防范读锁饥饿。它只是“不保证按请求顺序获取锁”,而非“偏向写锁”或“抑制读锁”。所谓“写锁优先”是常见误解。
非公平模式的真实行为
非公平模式指:新来的线程(无论读或写)可以和等待队列中的线程竞争锁。如果当前锁空闲,新线程可能直接抢到锁,不管队列里有没有等待者。
- 写线程抢到空闲写锁,是靠运气+竞争,不是调度策略倾斜
- 读线程同样可能在锁释放瞬间“插队”成功,尤其当读操作密集时
- 没有内置的“写锁唤醒优先级”或“读锁让渡机制”
读锁饥饿的真实成因
读锁饥饿通常发生在:持续有新读线程到达,而写线程始终无法抢到锁。这不是非公平模式的设计意图,而是高并发读场景下的自然结果。
- 每次写锁释放后,若立刻有多个读线程争抢,它们可能连续获得锁
- 写线程被阻塞在同步队列中,但新读线程不断通过“快速路径”(tryAcquireShared)抢占成功
- ReentrantReadWriteLock 不限制读线程数量,也不对写线程做唤醒保障
真正能缓解读饥饿的手段
若需避免写锁长期得不到执行,必须借助外部机制,而非依赖非公平模式:
立即学习“Java免费学习笔记(深入)”;
- 改用公平模式:new ReentrantReadWriteLock(true),确保FIFO排队,写线程不会被无限延后
- 降级写锁为读锁时谨慎操作:写锁降级允许,但若后续读锁被大量新读线程抢占,仍可能卡住写线程
- 控制读线程准入:例如用信号量限制并发读数量,为写操作留出窗口
- 使用StampedLock:其乐观读+validate机制更灵活,配合强制重试可减少写饥饿
非公平 ≠ 写优先,只是不保序
Java Doc 明确指出:非公平策略仅意味着“吞吐量通常更高”,但“可能导致某些线程长时间等待”。它不区分读写类型,也不引入任何偏向逻辑。写锁是否能及时获取,取决于线程调度、竞争强度和临界区长度等实际运行因素。
不复杂但容易忽略:想靠切换非公平模式来解决写饥饿,往往适得其反。


















