Java 当我们已经拥有重入锁时,再次锁定重入锁有什么帮助?

Java 当我们已经拥有重入锁时,再次锁定重入锁有什么帮助?,java,locking,java.util.concurrent,reentrantlock,Java,Locking,Java.util.concurrent,Reentrantlock,因此,如果当前线程再次获取锁,可重入锁将使计数增加1。我无法理解的是,为什么以及如何帮助我们或使我们受益?可重入锁执行此操作的原因是不再锁定已获得此锁的同一线程 例如:假设线程A正在获取可重入锁A。而线程B试图获取锁A,这将导致线程B被阻塞(可以找到更多关于线程状态的信息)。现在,线程A正在尝试(再次)获取锁A 因为可重入锁现在正在增加其计数,所以线程A没有被阻塞。线程A仍然可以访问锁并可以继续(锁存储有关深度的信息)。如果他(早晚)释放锁,计数将再次降低,以检查线程A是否仍然需要锁。如果计数为

因此,如果当前线程再次获取锁,可重入锁将使计数增加1。我无法理解的是,为什么以及如何帮助我们或使我们受益?

可重入锁执行此操作的原因是不再锁定已获得此锁的同一线程

例如:假设线程A正在获取可重入锁A。而线程B试图获取锁A,这将导致线程B被阻塞(可以找到更多关于线程状态的信息)。现在,线程A正在尝试(再次)获取锁A

因为可重入锁现在正在增加其计数,所以线程A没有被阻塞。线程A仍然可以访问锁并可以继续(锁存储有关深度的信息)。如果他(早晚)释放锁,计数将再次降低,以检查线程A是否仍然需要锁。如果计数为0,这意味着线程A每次获取时都已释放,线程B将获得对锁的访问权

如果没有重入,您现在将有一个。为什么?因为线程A拥有锁,并且会等待再次获得它



并发可能非常复杂,这有助于(稍微)降低这种复杂性。

这有助于在不寻常的情况下调用另一个也需要锁的方法

ReentrantLock lock = new ReentrantLock();

public void doSomething() {
    lock.lock();
    try {
        // Something.
    } finally {
        lock.unlock();
    }
}

public void somethingElse () {
    lock.lock();
    try {
        // Something else.
        // We can now call another locking method without risking my lock being released.
        doSomething();
    } finally {
        lock.unlock();
    }
}
在这里,public可以调用
doSomething
,它将获取锁,执行自己的操作,然后在调用
unlock
时释放锁


但是,当调用
somethingElse
并调用
doSomething
时,它只会增加锁计数。当
doSomething
解锁它时不会释放锁,它只会倒计时锁,将最后的解锁留在
somethingElse
中以释放锁。

增加锁的计数的目的是跟踪线程获得锁的次数,因此,在线程指示准备释放锁的次数相同之前,锁实际上不会被释放

假设用于锁定的命令将与用于释放锁的命令相匹配

假设我的代码进入代码段A,这需要锁

然后,在不退出代码段A的情况下,它进入代码段B,代码段B也需要相同的锁。正如你所注意到的,我们有锁,所以我们不需要封锁

但是我们将离开B部分,B部分是用来在我们退出锁时释放锁的。(否则,到达B节但尚未锁定的代码将永远不会释放锁定。)

不过,我们仍然在A部分,所以我们还不想真正放弃锁,或者在A部分时,另一个线程可以使用它

因此,当我们进入B部分时,我们增加了锁计数,这意味着当我们退出B部分时,我们可以将计数减少1,并且看到它没有返回到0,就不会释放它


然后,当A部分再次释放锁时,计数会回落到0,这就是我们真正释放锁的时候。

欢迎来到StackOverflow!看起来你的问题并不是关于Java的,因为可重入锁是一个远远超出了单一语言的概念。在此基础上,它可能已经有了答案。也给出了一些解释。根据JavaDoc(见我上面的评论),
ReentrantLock
确实具有“与使用同步方法和语句访问的隐式监视器锁相同的基本行为和语义”下面是一个使用关键字
synchronized
查看重入操作的简单示例。这会造成一些相当误导性的逻辑跳跃,并且只简要/顺便提到了基于计数器的锁定解决的真正问题。@MarkAdelsberger我提供了一个示例,该示例使用源代码查找内容。为什么我只是简单地/顺便提及真正的问题?问题不是“什么是死锁”,而是为什么需要计数器。计数器不能解决死锁。它解决了过早释放锁的问题。这就是我的观点。@MarkAdelsberger你是对的,但这也可以防止死锁。如果您对不可重入的锁具有访问权限并再次获取它,则结果将是死锁。计数器不会阻止死锁。允许持有锁的线程在不保留计数器的情况下通过其他锁调用是完全可能的。难道我们不能用其他锁来保护doSomething()吗?是因为性能问题吗?@PeerNet,如果你愿意的话。但你为什么要这样?我想把脑子里的事情弄清楚。如果我们没有ReentrantLock,我们可以使用其他锁对象,对吗?我想了解ReentrantLock的需求,它为我们提供了什么?不创建另一个锁并节省一些空间?