3

ReentrantReadWriteLock文档中说:

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

如果我理解正确,这意味着您可以从同一个线程执行:

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

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

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

为什么必须先解锁read才能锁定write在同一个线程中?

4

2 回答 2

4

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

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

如果一个线程获得了一个写锁,它也隐含地拥有读权限,所以可以授予读锁的获得,因为它并没有真正违反锁的契约(如果我可以写,我可以读)也锁持有人的期望(我为写作而锁定,所以我现在是唯一一个可以读写的人)。

于 2017-03-29T16:52:21.207 回答
0

我实际上并不知道答案,但它可能是为了帮助您避免编写可能死锁的代码。

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

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

通过不允许您将读锁升级为写锁,他们使您无法编写以这种特定方式死锁的程序。

于 2017-03-29T16:52:39.770 回答