读写锁通过分离读写锁需求提升并发性能,读操作可并行、写操作独占,适用于读多写少场景;读锁共享、写锁排他,支持降级但不可升级;写占比超10%~15%时性能反降,需依场景合理选型。

读写锁能提升并发性能,关键在于它把“读”和“写”两种操作的锁需求拆开处理——读操作可以并行,写操作保持独占。这在读多写少的场景(比如缓存、配置中心、只读报表)中效果最明显。
读读不互斥,大幅释放读请求压力
多个线程同时调用读方法时,只要没有写锁在持有,它们都能立刻拿到读锁并执行。不像 synchronized 或 ReentrantLock 那样强制串行,避免了“一万个人抢一扇门”的低效局面。
- 读锁是共享锁,底层通过 AQS 的共享模式实现
- 高并发读场景下,吞吐量可接近线性增长
- 注意:读锁持有时间要短,不能在
readLock.lock()块里做 RPC、DB 查询或耗时日志
读写/写写严格互斥,保障数据一致性
写锁是排他锁,获取时必须确保当前没有读锁和写锁被占用。这就天然保证了写操作的原子性和可见性,也防止了脏读、幻读等并发问题。
- 写锁升级不可行:已有读锁时再申请写锁会死锁,必须先释放读锁再争写锁
- 支持写锁降级:一个线程先持写锁,再获取读锁,最后释放写锁——适合“修改后立即读取”的逻辑
- 降级必须在同一线程内完成,且不能跨方法或异步执行
合理选型:不是所有场景都适合读写锁
它不是万能加速器。当写操作占比超过 10%~15%,读写锁的 CAS 和状态位运算开销反而比 synchronized 更重,性能可能下降。
- 写频高、读写比例接近的场景,优先考虑
ReentrantLock或分段锁(如ConcurrentHashMap) - 对响应延迟敏感、写操作频繁,可启用公平模式:
new ReentrantReadWriteLock(true) - 默认非公平模式吞吐更高,但长等待线程可能被持续插队
正确使用三原则
很多性能问题其实来自误用,而不是锁本身设计缺陷。
-
lock/unlock 必须严格配对:
readLock().lock()只能由readLock().unlock()释放,混用会导致永久阻塞 - 读操作不能有副作用:读锁只保护对共享变量的读取动作,构造对象、发通知、打日志等行为必须移出锁块
-
避免锁粒度失衡:例如用读写锁保护整个大 Map,但每次只查一个 key——此时更适合无锁结构(如
CopyOnWriteArrayList)或更细粒度分段控制
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











