当我们已经锁定可重入锁时,再次锁定可重入锁有何帮助?

how does locking a reentrant lock again helps when we already have the lock on it?

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

可重入锁这样做的原因是为了不再锁定已经获得此锁的同一个线程。

例如:假设您有线程 A 正在获取可重入锁 A。然后线程 B 尝试获取锁 A,这将导致线程 B 被阻塞(有关线程状态的更多信息,请参见 here).现在,线程 A 正在尝试(再次)获取锁 A。

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

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


并发性可能非常复杂,reentrancy 有助于(只是一点点)降低这种复杂性。

当您想调用另一个也需要锁的方法时,这有助于解决异常情况。

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 部分的代码将永远不会释放锁定。)

不过,我们仍在 A 部分,所以我们不想真的放弃锁,否则其他线程可能会在我们进入时占用它A 部分

所以当我们进入 B 部分时,我们增加了锁定计数,这意味着当我们退出 B 部分时,我们可以将计数减一,看到它没有回到 0,而不是释放它。

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