ReentrantReadWriteLock疑问:读多写少场景下写线程会永久挂起吗?
ReentrantReadWriteLock读写锁的写线程饥饿问题
是的,这种**写线程永久挂起(饥饿)**的情况是可能发生的,核心原因在于ReentrantReadWriteLock的默认锁策略:
默认非公平锁模式下,读锁是共享且可重入的。当有读线程持有读锁时,后续新来的读线程可以直接获取读锁,无需排队;而写线程必须等待所有读锁释放后才能获取写锁。如果你的应用是读密集型,读请求源源不断,写线程会一直被排在所有新来的读线程后面,永远没机会拿到锁,最终陷入永久等待。
如果你想避免这种情况,可以在初始化锁时指定公平模式:
ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true);公平模式下,锁的获取严格按照线程排队顺序执行。当写线程进入等待队列后,后续的读线程不能插队,必须等写线程完成并释放锁后,才能继续获取读锁。这能保证写线程不会被饿死,但代价是读操作的吞吐量会下降——因为读线程不能再并发抢占锁,必须按顺序等待。
针对你的读密集、写极少的场景:
- 如果写操作是必须保证执行的(比如数据更新不能无限延迟),建议开启公平锁;
- 如果写操作对延迟容忍度较高,能接受偶尔长时间等待,默认的非公平锁可以保留,毕竟它能最大化读操作的并发效率。
内容的提问来源于stack exchange,提问作者aman goyal
相关产品推荐
相关产品推荐

