Java 读写洛克。了解从readLock升级到writeLock

Java 读写洛克。了解从readLock升级到writeLock,java,multithreading,readwritelock,Java,Multithreading,Readwritelock,考虑这个JDK标准接口: public interface ReadWriteLock{ public Lock readLock(); public Lock writeLock(); } Goetz在Java并发实践中提到,从readLock升级到writeLock容易死锁 如果两个读卡器同时尝试升级到写锁, 两者都不会实现读锁 让我困惑的是,有两个读者试图升级。但是一个读者就足够了,不是吗?如果读卡器尝试升级,则尚未释放读锁。在读取锁保持的情况下尝试获取写入锁是死锁 因此

考虑这个
JDK
标准接口:

public interface ReadWriteLock{
    public Lock readLock();
    public Lock writeLock();
}
Goetz在Java并发实践中提到,从readLock升级到writeLock容易死锁

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


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


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

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

(这一切都被术语“锁”的重载搞糊涂了——它既是一个动词又是一个名词,也就是说,一个人可以锁一把锁)

<> >而不是思考<代码> Read RealObjy[/COD> <代码> Read Orthue/Cuff>方法和 RoeLooks方法返回实际锁,考虑他们实际做的是返回一个抽象机制,允许获取不同类型的锁(在同一个、单一的、读写锁定机制上)。 读写锁(机制)是一个单锁,可以通过两种方式锁定:读锁定和写锁定。读写锁可以被一个或多个线程同时读锁定,也可以被写锁定。它永远不能同时被读锁定和写锁定


如果读卡器尝试升级,则尚未释放读锁。在读取锁保持的情况下尝试获取写入锁是死锁

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

因此,单线程将其读锁升级为写锁在概念上没有问题;它只需要等待读取锁的所有其他持有者放弃它,然后才能进行升级。在这种情况下不可能出现僵局

例如,假设有三个线程——A、B和C,它们都已读取并锁定了锁。线程A尝试升级到写锁。这意味着它必须等待B和C放弃读锁。这种情况最终会发生,此时线程A获得一个写锁(最终,线程A将放弃该锁)

另一方面,考虑A和B是否都尝试升级到写锁。这意味着他们都在等待另一方放弃读锁,而这不会发生;为了让线程A放弃读锁,它首先需要获取写锁,这在线程B放弃读锁之前不会发生,在线程A放弃读锁之前不会发生。。。等等出现了僵局


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

“试图在持有读锁的情况下获取写锁是死锁的”-这是什么意思?你认为这是为什么?