ReentrantReadWriteLock - 为什么读者不能获得作家的锁?

时间:2017-03-29 16:27:46

标签: java multithreading locking reentrantreadwritelock

ReentrantReadWriteLock文档中说:

writer can acquire the read lock, but not vice-versa

如果我理解正确,则意味着您可以执行相同的主题:

//thread1
lock.writeLock().lock()
lock.readLock().lock()
print("this line executes")

这是有道理的:如果你已经锁定write,则没有其他线程可以输入锁定的代码。但是如果你锁定read,如果没有其他线程让write锁定,为什么不能在同一个线程中输入read块?所以这不起作用:

//thread1
lock.readLock().lock()
lock.writeLock().lock()
print("this line doesn't execute")

为什么在锁定read之前必须解锁write

2 个答案:

答案 0 :(得分:2)

ReentrantReadWriteLock并不意味着不遵循正常的规则锁定。

如果线程获取了用于读取目的的锁,则期望目标数据的值在锁定期间不会改变。否则会阻止可重复读取。从概念上讲,如果你让一个线程(相同或另一个)在读锁定时获得写锁定,那么你就违反了该规则。

如果某个线程获得了写入锁定,它也隐含地具有读取权限,因此可以获得读取锁定,因为它并没有真正违反锁定合同(如果我能写,我可以阅读)也没有锁定器的期望(我因为写作而被锁定所以我是唯一一个可以读取或写入的人)。

答案 1 :(得分:-1)

我实际上知道答案,但它可能会帮助您避免编写可能导致死锁的代码。

假设您有两个执行相同代码的线程。两个线程都获得了读锁定。然后,两个线程都尝试获取写锁定。在另一个线程释放其读锁定之前,这两个线程都不能继续,但是当它等待升级时,两个线程都不会释放它的读锁定。

一个不同的实现可以检测到死锁,并在发现它时在两个线程中抛出异常,但也许有人认为(A)会对不需要死锁检测的应用程序的性能产生负面影响,或者(B)复杂化API太多了。

通过禁止您将读锁升级为写锁,他们已经无法编写以特定方式死锁的程序。