ReentrantReadWriteLock 通过读锁共享、写锁独占机制显著提升高读低写场景性能;适合配置中心等读多写少场景,支持重入和锁降级,但不可读锁升级写锁,非公平模式默认吞吐更高。

ReentrantReadWriteLock 能显著提升高读低写的并发场景性能,核心在于允许多个线程同时读、但读写/写写互斥——这比单纯用 synchronized 或 ReentrantLock 更精细地分离了读操作的并发需求。
读锁共享,写锁独占
ReentrantReadWriteLock 内部维护一对锁:ReadLock 和 WriteLock。多个线程可同时持有 ReadLock(只要没线程持有 WriteLock);而 WriteLock 是排他性的,一旦有线程在写,所有读和写都必须等待。
- 适合“读多写少”的典型场景,比如配置中心、缓存数据、元数据查询等
- 读锁不阻塞其他读锁,避免了 synchronized 对整个临界区的粗粒度加锁
- 写锁获取前会等待所有当前读锁释放,确保写操作的可见性和一致性
正确使用 readLock 和 writeLock
必须成对调用 lock() / unlock(),且推荐用 try-finally 保证解锁,否则可能造成锁泄漏。
- 读操作示例:readLock.lock(); try { /* 读取共享变量 */ } finally { readLock.unlock(); }
- 写操作示例:writeLock.lock(); try { /* 修改共享变量 */ } finally { writeLock.unlock(); }
- 不要在持有读锁时直接升级为写锁(会死锁),如需“读-改-写”,应先释放读锁再抢写锁
注意锁的公平性与重入性
默认是非公平锁(吞吐量更高),也可通过构造函数启用公平模式(new ReentrantReadWriteLock(true)),此时按等待顺序分配锁,但会降低并发吞吐。
立即学习“Java免费学习笔记(深入)”;
- 读锁和写锁都支持重入:同一线程可多次获取同一把锁,但需对应次数的 unlock()
- 写锁可降级为读锁(持有写锁后,再获取读锁,然后释放写锁),这是唯一安全的“锁升级”路径
- 读锁不能升级为写锁,否则破坏锁协议,JVM 直接抛 UnsupportedOperationException
对比 synchronized 和普通 ReentrantLock
在纯读场景下,synchronized 或 ReentrantLock 会让所有读线程串行执行;而 ReadLock 允许并行,QPS 可提升数倍(具体取决于线程数和读操作耗时)。
- 但写操作性能略低于 ReentrantLock(因需协调读写状态,有额外开销)
- 内存占用稍高(内部需维护读写状态、等待队列等)
- 不是万能替代:若写操作频繁,或读操作本身很重(如含复杂计算或 I/O),读写锁优势会减弱甚至变负优化
基本上就这些。用对场景、写对结构、避开升级陷阱,ReentrantReadWriteLock 就是提升读并发的实用利器。











