读写锁仅在读远多于写时性能更优,读-读不互斥提升并发,但写占比超15%~20%或操作轻量时反拖慢;支持写锁降级但禁止升级,公平模式可防写饥饿但增调度开销。

读写锁在多线程并发读场景中性能优势明显,但前提是读操作远多于写操作——它不是“万能加速器”,而是针对特定访问模式的精准优化工具。
读-读不互斥,天然提升并发吞吐
普通互斥锁(如 synchronized 或 ReentrantLock)下,哪怕100个线程都在读,也必须排队串行执行;而 ReentrantReadWriteLock 的读锁是共享锁,多个线程可同时持有。只要没有写线程在操作,读请求几乎零阻塞。
- 适合缓存查询、配置读取、权限校验等高频只读场景(例如95%以上为读)
- 实测中,读线程数从10增至100时,吞吐量常呈近似线性增长,而互斥锁则趋于饱和甚至下降
- 底层通过 AQS 的共享模式实现,状态变量高16位计数读锁重入次数,开销可控
读-写/写-写严格互斥,保障数据一致性
读写锁并未牺牲安全性:写锁仍是独占的,且与读锁互斥。这意味着:
- 写操作发生时,所有新读请求会等待;已有读锁全部释放后,写锁才可获取
- 写锁可降级为读锁(先 unlock 写锁,再 lock 读锁),支持“写后立即读”的常见逻辑
- 但禁止锁升级(持有读锁时无法获取写锁),否则会导致死锁——这是设计约束,不是 bug
性能优势有明确边界,超限反而拖慢
读写锁自带额外状态管理、CAS 操作和队列维护开销。当不满足以下条件时,它可能比普通锁更慢:
立即学习“Java免费学习笔记(深入)”;
- 写操作占比超过 15%~20%,线程频繁切换读/写状态,调度成本上升
- 单次读操作极轻量(如仅读一个
int字段),锁本身的开销已超过临界区执行时间 - 读锁持有时间过长(比如在锁内做远程调用或 I/O),导致写线程长期饥饿
- 保护对象本身已是线程安全的(如
ConcurrentHashMap),加读写锁纯属冗余
公平性设置影响调度行为,需按需启用
默认非公平模式下,写线程可能插队抢占刚释放的锁,造成读线程持续活跃而写线程“饿死”。若业务对写操作延迟敏感(如实时配置更新),应启用公平模式:
new ReentrantReadWriteLock(true)- 启用后需监控
getQueueLength()和hasQueuedThreads(),避免因过度公平带来上下文切换开销 - 高吞吐写场景(如日志聚合)通常更适合非公平模式



















