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

时间:2018-08-30 12:58:51

标签: java locking java.util.concurrent reentrantlock

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

3 个答案:

答案 0 :(得分:1)

可重入锁正在执行此操作的原因是,不要再次锁定已获得此锁的同一线程。

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

由于可重入锁现在正在增加其计数,因此线程A未被阻塞。线程A仍具有对锁的访问权限,并且可以继续(锁存储有关深度的信息)。如果他(早晚)释放了该锁,则计数将再次降低,以检查线程A是否仍需要该锁。如果计数变为0,则意味着线程A每次获取线程A都已释放,线程B将通过Lock获得访问权限。

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


并发可能真的很复杂,deadlock有助于(略微降低)这种复杂性。

答案 1 :(得分:0)

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

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();
    }
}

在这里公众可以调用doSomething,它将获取锁,执行此操作,然后在调用unlock时释放锁。

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

答案 2 :(得分:0)

增加锁计数的目的是跟踪线程获取锁的次数,这样,直到线程指示准备好释放相同次数的锁之后,锁才会真正释放。

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

说我的代码进入代码部分A,该部分需要锁。

然后,在不退出代码部分A的情况下,它输入代码部分B,也需要相同的锁。如您所见,我们拥有锁,因此我们无需阻止。

但是我们将离开B节,编写B节以在退出时释放锁。 (否则到达B节而没有锁的代码将永远不会释放锁。)

尽管如此,我们仍在A节中,所以我们不想真的放弃锁,否则当我们在A节中时,另一个线程可能会抢走它。

>

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

然后,当A节再次释放锁时,计数回落到0,而 是我们真正放开锁的时间。