读写锁.了解从 readLock 升级到 writeLock [英] ReadWriteLock. Understanding upgrading from readLock to writeLock

查看:61
本文介绍了读写锁.了解从 readLock 升级到 writeLock的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个JDK标准接口:

public interface ReadWriteLock{
    public Lock readLock();
    public Lock writeLock();
}

B.Goetz 在 Java Concurrency 实践中提到从 readLock 升级到 writeLock 容易死锁.

B. Goetz in Java Concurrency in practice mentioned upgrading from readLock to writeLock is deadlock-prone.

如果两个读者同时尝试升级到写锁,也不会实现读锁.

If two readers simultaneously attempt to upgrade to a write lock, neither will realese the read lock.

让我感到困惑的是,两个 读者正在尝试升级.但即使一位读者就足够了,不是吗?如果读取器尝试升级,则尚未释放读取锁.试图在持有读锁的情况下获取写锁是死锁的.

The thing that's confused me is that it was two readers attempting to upgrade. But even one reader is enough, isn't? If a reader tries to upgrade it's not released the read lock yet. Trying to acquire the write lock with the read lock held is deadlocky.

因此,我认为提供升级操作在理论上甚至是荒谬的.或者也许一个实现可以解决这个问题?

So judging by that I think it's even theoretically nonsensical to provide the upgrade operation. Or maybe an implementation can take care of that?

推荐答案

听起来您正在考虑将读锁"和写锁"视为构成读写锁的两种不同锁.这不是正确的思考方式,即使 API 似乎公开了这样的组合(通过提供方法来获取对写锁"和读锁"的引用).

It sounds like you are considering a "read lock" and a "write lock" to be two different locks which compose a read-write lock. That's not the correct way to think about it, even though the API seems to expose such a composition (by providing methods to obtain a reference to the "write lock" and to the "read lock").

(这一切都被术语锁"的重载所混淆——它既是一个动词又是一个名词,也就是说,一个人可以lock 一个 lock).

(This is all confused a little by the overloading of the term "lock" - it is both a verb and a noun, that is, one can lock a lock).

与其认为 ReadWriteLockreadLock 方法和 writeLock 方法返回实际的锁,不如考虑它们实际做的是返回一个抽象机制允许获取不同类型的锁(在相同、单一、读写锁机制上).

Rather than thinking that ReadWriteLock's readLock method and writeLock method return actual locks, consider that what they actually do is return an abstract mechanism allowing acquisition of different types of lock (on the same, single, read-write lock mechanism).

读写锁(机制)是一个锁,可以通过两种方式锁定:读锁定写锁定.读写锁可以被一个或多个线程并发读锁定,也可以写锁定.它永远不能同时被读和写锁定.

A read-write lock (mechanism) is a single lock which can be locked in two ways: read-locked and write-locked. The read-write lock can be read-locked by one or more threads concurrently, or it can be write-locked. It can never be both read- and write- locked at the same time.

如果读取器尝试升级,它尚未释放读取锁.试图在持有读锁的情况下获取写锁是死锁的.

If a reader tries to upgrade it's not released the read lock yet. Trying to acquire the write lock with the read lock held is deadlocky.

写锁强于读锁;它就像一个带有附加属性的读锁(没有其他线程也可以持有该锁).从读锁升级到写锁并不是在已经持有另一个锁时获取另一个锁;相反,它是关于更改已持有在单个锁上的锁的类型.

A write lock is stronger than a read lock; it is like a read lock with an additional property (that no other thread may also hold the lock). Upgrading from a read-lock to a write-lock is not about acquiring one lock when another is already held; rather, it's about changing the type of lock which is already held on a single lock.

因此,单线程将其读锁升级为写锁不存在概念上的问题;它只需要等待读锁的所有其他持有者在升级发生之前放弃它.这种情况下不存在死锁的可能.

So, there is no conceptual problem with a single thread upgrading its read lock to a write lock; it just needs to wait until all other holders of the read lock relinquish it before the upgrade can occur. There is no possibility of deadlock in this case.

例如,假设有三个线程 - A、B 和 C,它们都对锁进行了读锁定.线程 A 尝试升级到写锁.这意味着它必须等待 B 和 C 放弃他们的读锁.这最终会发生,此时线程 A 获得了一个写锁(并且,最终,线程 A 将释放这个锁).

For instance, suppose there are three threads - A, B, and C, all which have read-locked the lock. Thread A tries to upgrade to a write-lock. This means it must wait for B and C to relinquish their read lock. This eventually happens, and at that point thread A acquires a write lock (and, eventually, thread A will then relinquish this lock).

另一方面,考虑 A 和 B 是否都尝试升级到写锁.这意味着他们都在等待另一个放弃读锁,这不会发生;对于线程 A 放弃读锁,它首先需要获取写锁,直到线程 B 释放读锁才会发生这种情况,直到它获得写锁才会发生这种情况,这不会发生直到线程 A 放弃读锁……依此类推.有一个僵局.

On the other hand, consider if both A and B try to upgrade to a write lock. This means they are both waiting for the other one to relinquish the read lock, which won't happen; for thread A to relinquish the read lock, it would first need to acquire the write lock, which won't happen until thread B relinquishes the read lock, which it won't do until it acquires the write lock, which won't happen until thread A relinquishes the read lock ... and so on. There is a deadlock.

Java API 不允许从读锁升级到写锁,因为这可以防止死锁情况.编写一个可以安全升级锁类型的程序是可能的(如果有点棘手),但无论如何 Java API 都不允许这样做.

The Java API doesn't allow upgrading from a read-lock to a write-lock, since this prevents the deadlock scenario. It would be possible (if a little tricky) to write a program that could safely upgrade the lock type, but the Java API doesn't allow it regardless.

这篇关于读写锁.了解从 readLock 升级到 writeLock的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆