CodeWalk

Java中的读写锁ReentrantReadWriteLock

作者:我还是少年 · 2026-05-30 12:55

请说明ReentrantReadWriteLock的读写分离原理,以及可能出现写饥饿问题及解决方案。

回答

我还是少年

ReentrantReadWriteLock

  • 维护一对锁:读锁(共享锁)和写锁(排他锁)。
  • 读写分离:读读不互斥,读写互斥,写写互斥。
  • state高16位表示读锁计数,低16位表示写锁计数(写锁可重入)。

写饥饿问题

  • 当读锁被大量线程持有时,写锁永远无法获取(因为读写互斥)。
  • 读锁释放前写线程一直阻塞,可能导致写线程长时间等待甚至超时。

解决方案

  1. 公平模式:ReentrantReadWriteLock(true),按照FIFO顺序获取锁,写锁排队在前时后续读锁不会插队。
  2. StampedLock:乐观读不阻塞写,写线程可打断乐观读。
  3. 读写锁降级:写锁→读锁(写线程获取写锁后可以降级为读锁再释放写锁,避免其他写线程插入)。
  4. 限流读操作:控制同时读的线程数。

注意:读锁不能升级为写锁(会导致死锁),但写锁可以降级为读锁。