readwritelock通过“读读共享、读写互斥”提升读多写少场景并发性能:读操作可并行执行,写操作独占且精准阻塞;误用(如读锁内耗时操作、未释放锁、读锁升级)反而更慢;非公平模式默认更优。

ReadWriteLock 通过“读读共享、读写互斥”的机制,在读多写少场景下显著提升并发性能。它不是简单地换一把锁,而是改变了锁的语义粒度:让不修改数据的读操作并行化,只对真正有冲突的写操作施加排他约束。
读操作可以真正并发执行
多个线程同时调用 readLock().lock() 不会互相阻塞——只要没有线程持有写锁,它们就能并行进入临界区。这和 synchronized 或 ReentrantLock 完全不同,后者会让所有线程(无论读写)排队等待同一把锁。
- 例如缓存查价格:100个请求同时读,用普通锁要串行处理;用读写锁可近乎并行完成,QPS 理论上接近线性提升
- CPU 缓存行复用更高效,多个读线程密集访问同一块内存,减少主存访问延迟
- 线程上下文切换大幅减少,调度开销下降
写操作仅短暂阻塞必要线程
写锁是独占的,但它的影响范围被精准控制:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 写线程必须等所有当前读锁释放后才能获得写锁,确保写入前数据状态一致
- 一旦写锁获取成功,后续新来的读请求会被挂起,但已进入读操作的线程不受影响(即不会中途中断)
- 写操作本身不因读锁存在而变慢,只是获取时机受读锁占用时长制约
避免常见误用,才能发挥真实优势
读写锁不是“用了就快”,错误用法反而比 synchronized 更慢:
- 读锁内做耗时操作(如远程调用、大对象拷贝),会导致写线程长期饥饿
- 忘记在
finally中unlock(),或跨线程释放,引发死锁或阻塞 - 试图在持有读锁时直接调
writeLock().lock()—— 这会永久阻塞,JVM 不支持读锁升级 - 写操作占比超过 20%,锁协调开销反超收益,此时应退回
ReentrantLock
非公平模式更适合大多数生产环境
默认构造的 new ReentrantReadWriteLock() 是非公平的,这意味着:
- 新来的读线程可能插队,略增加写线程等待时间,但整体吞吐高 15%~30%
- 公平模式(传
true)虽保障等待顺序,但唤醒逻辑更重,且不能解决“已有大量读锁未释放”导致的写饥饿 - 除非监控发现写锁平均等待超 50ms,否则无需开启公平模式
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










