因此,如果当前线程再次获得该锁,则可重入锁将计数加一。我无法理解的是为什么以及如何帮助或使我们受益?
答案 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,而 是我们真正放开锁的时间。