在ReentrantReadWriteLock中,读锁和写锁有关联吗?

6

请帮我解释一下这份合同。我不确定ReentrantReadWriteLock中的两个锁是否有关联?还是只是两个普通锁的捆绑包?

2个回答

10
它允许多个线程同时读取资源,但需要一个线程等待独占锁才能写入资源。
规则如下:
- 多个读者可以同时共享资源。如果您拥有读取锁,则可以安全地获取另一个读取锁。共享锁的最大计数为1111 1111 1111 1111。 - 如果您拥有读取锁,则无法获取写入锁。 - 如果您拥有写入锁,则无法在任何其他线程中获取读取锁。 - 只有在没有其他线程中活动的写入器时,读取器才能访问资源。 - 如果您拥有写入锁,则可以在同一线程中获取另一个写入锁。线程可以拥有的独占锁的最大计数为1111 1111 1111 1111。 - 只有在没有来自不同线程的其他读取器或写入器处于活动状态时,写入器才能访问资源。它优先考虑写入器而不是读取器。也就是说,如果一个写入器正在等待锁定,则不允许其他线程的新读取器访问资源。现有的读取器可以继续使用资源,直到它们释放锁定。这可以防止所谓的“写入器饥饿”。 - 允许从写入锁降级为读取锁,方法是获取写入锁,然后获取读取锁,最后释放写入锁。但是,从读取锁升级到写入锁是不可能的。
内部使用int值维护锁状态(c)。在这种情况下,由于我们有读取和写入锁,因此逻辑上分为两个shorts:较低的short表示独占(写入)锁持有计数,而较高的short表示共享(读取)持有计数。
假设锁的当前状态为 c = xxxx xxxx xxxx xxxx yyyy yyyy yyyy yyyy, 则读取器锁的数量为上位bits xxxx xxxx xxxx xxxx。
写入器锁的数量为下位bits yyyy yyyy yyyy yyyy。

基于什么?如果您拥有写锁,则无法在任何其他线程中获取读锁。 - AlikElzin-kilaka
“更喜欢写作者而非读者” - 基于什么? - AlikElzin-kilaka

2

如果线程正在等待读取锁定,那么它是共享的,但是当线程想要获取写锁定时,只有该线程被允许访问,就像互斥一样。

因此,只允许其中一个操作。 如果锁由读者持有,并且线程请求写锁,则在获得写锁的线程释放它之前,不再允许其他读取者获取读取锁定。


2
ReentrantReadWriteLock 的设计是这样的,当有人正在读取时,您 无法 获取写锁,反之亦然。 这就是设计意图的一部分。 - Louis Wasserman
1
@Dims 是的。在这种情况下没有区别,我认为应该将其记录下来。 - Amit Deshpande
1
@Dims 是的。一个线程可以获取两个锁。请参阅Javadocs - Amit Deshpande
1
@Dims 我猜这个链接会比Java文档更清晰。Java文档隐含地说明了它是“写锁是独占的”。 - Amit Deshpande
1
当有人在读取时,您无法获取写锁,反之亦然。只要没有线程在写入,您可以在其他线程正在读取时获取读锁。这就是与单个锁的区别。 - Louis Wasserman
显示剩余13条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接