如何利用ReentrantReadWriteLock的锁降级,在确保强一致性的同时,最大化读并发改写长尾词?
- 内容介绍
- 相关推荐
本文共计867个文字,预计阅读时间需要4分钟。
这是`ReentrantReadWriteLock`的唯一许可降级式,其他任何组合都会阻塞或抛出异常。
- 写锁未持有时直接调
readLock.lock():正常,但和降级无关 - 已持读锁再调
writeLock.lock():必然死锁(读写不可重入) - 两个线程分别持读锁和写锁:写锁会等所有读锁释放,读锁会等写锁释放 → 互斥生效
- 写锁释放后才加读锁:不算降级,只是普通读操作,不保证中间无修改
关键点在于:降级过程中,写锁必须**一直持有**,直到读锁成功获取后,才能释放写锁。否则数据可能被其他写线程篡改。
为什么不能“先释放写锁再加读锁”
看似省事,实则破坏强一致性:
- 写操作完成后,若立即
writeLock.unlock(),其他写线程可能瞬间抢占并修改数据 - 此时你再
readLock.lock(),拿到的是别人刚写的新值,而非你刚写完的那版 - 你本意是“我写了,然后立刻读自己写的”,结果变成“我写了,别人抢着改了,我读到别人的”
降级正是为堵住这个窗口:JVM 保证在同一线程内,readLock.lock() 成功返回前,writeLock 仍有效,其他写线程无法插入。
本文共计867个文字,预计阅读时间需要4分钟。
这是`ReentrantReadWriteLock`的唯一许可降级式,其他任何组合都会阻塞或抛出异常。
- 写锁未持有时直接调
readLock.lock():正常,但和降级无关 - 已持读锁再调
writeLock.lock():必然死锁(读写不可重入) - 两个线程分别持读锁和写锁:写锁会等所有读锁释放,读锁会等写锁释放 → 互斥生效
- 写锁释放后才加读锁:不算降级,只是普通读操作,不保证中间无修改
关键点在于:降级过程中,写锁必须**一直持有**,直到读锁成功获取后,才能释放写锁。否则数据可能被其他写线程篡改。
为什么不能“先释放写锁再加读锁”
看似省事,实则破坏强一致性:
- 写操作完成后,若立即
writeLock.unlock(),其他写线程可能瞬间抢占并修改数据 - 此时你再
readLock.lock(),拿到的是别人刚写的新值,而非你刚写完的那版 - 你本意是“我写了,然后立刻读自己写的”,结果变成“我写了,别人抢着改了,我读到别人的”
降级正是为堵住这个窗口:JVM 保证在同一线程内,readLock.lock() 成功返回前,writeLock 仍有效,其他写线程无法插入。

