reentrantreadwritelock 的核心价值在于读写分离,允许多个读线程并发执行、写操作独占执行,通过高位16位记读锁数、低位16位记写锁重入次数,支持锁降级但不支持升级,适用于读多写少场景。

ReentrantReadWriteLock 的核心价值在于它把“读”和“写”拆成两种独立的访问策略,专为读多写少的场景而生。它不靠粗暴地锁住整个资源,而是让读操作并发执行、写操作独占执行,在保证线程安全的前提下显著提升吞吐量。
读写分离如何真正提升并发性能
传统互斥锁(如 ReentrantLock)对读写一视同仁:哪怕100个线程都在读,也得排队。而 ReentrantReadWriteLock 允许多个读线程同时进入临界区,只要没人正在写。这意味着在缓存读取、配置查询、报表统计等典型场景中,大量只读请求不再互相阻塞。
- 读读共享 → 多个读线程可并行执行,不竞争
- 读写互斥 → 有写操作时,所有新读请求必须等待
- 写写互斥 → 写操作始终串行,确保修改原子性
底层状态如何用一个 int 精确管理两类锁
它复用 AQS 的 state 字段(32位 int),通过位拆分实现双计数:
- 高16位(bit 16–31)记录当前持有读锁的线程数(共享计数)
- 低16位(bit 0–15)记录当前写锁被同一线程重入的次数(独占计数)
- 例如 state = 0x00030002 表示:3个线程在读,写锁被重入了2次
这种设计避免了额外对象开销,也使得状态更新(CAS)仍能保持原子性,是高性能的关键基础。
锁降级:唯一允许的“写→读”升级路径
ReentrantReadWriteLock 支持锁降级——即持有写锁的线程,可在不释放写锁的前提下,直接获取读锁。这常用于“先修改后立即读取”的逻辑,避免中间状态被其他线程干扰。
- 不允许锁升级:持有读锁的线程不能直接获取写锁(否则会死锁)
- 降级必须在同一现场完成:写锁未释放前,调用 readLock().lock()
- 降级后,写锁仍有效,读锁计数增加;释放顺序无强制要求,但建议按获取逆序释放
实际使用中的关键注意事项
它不是万能银弹,误用反而引发问题:
- 写操作频繁时,读线程会长时间饥饿——因每次写都会阻塞所有新读请求
- 读锁不支持条件变量(Condition),只有写锁可关联 Condition 实例
- 务必在 finally 块中释放锁,否则极易导致死锁或资源泄露
- 非公平模式下,写锁可能插队,加剧读线程等待;若需更均衡调度,可选用公平模式构造器
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











