Java中“ReentrantLock”的含义是什么?
重入意味着锁是按线程而不是按调用获取的。
既然固有锁是由线程持有的,这难道不意味着线程运行一次等于调用基础吗?
谢谢,它似乎意味着:在一个线程中,如果我在处理函数时得到一个锁,哪个调用函数,并且还需要一个锁,那么就会有一个重入。在Java中,这种现象是按线程获取的,所以我不需要考虑死锁吗?lockA
doA
doB
doB
lockA
重入意味着锁是按线程而不是按调用获取的。
既然固有锁是由线程持有的,这难道不意味着线程运行一次等于调用基础吗?
谢谢,它似乎意味着:在一个线程中,如果我在处理函数时得到一个锁,哪个调用函数,并且还需要一个锁,那么就会有一个重入。在Java中,这种现象是按线程获取的,所以我不需要考虑死锁吗?lockA
doA
doB
doB
lockA
重入意味着锁是按线程而不是按调用获取的。
这是一个误导性的定义。这是真的(某种程度上),但它错过了真正的重点。
重入意味着(一般CS / IT术语)你做了某事,当你还在做的时候,你又做了一次。在锁的情况下,这意味着你在单个线程上做这样的事情:
使用重入锁定/锁定机制,尝试获取相同的锁定将成功,并将增加属于该锁的内部计数器。只有当锁的当前持有者释放了两次锁时,才会释放锁。
这是Java中使用原始对象锁/监视器的示例...可重入的:
Object lock = new Object();
...
synchronized (lock) {
...
doSomething(lock, ...)
...
}
public void doSomething(Object lock, ...) {
synchronized (lock) {
...
}
}
重入锁定的替代方法是非重入锁定,其中线程尝试获取已持有的锁定将是错误的。
使用重入锁的优点是,您不必担心由于意外获取已持有的锁而失败的可能性。缺点是,您不能假设您调用的任何内容都不会更改锁旨在保护的变量的状态。但是,这通常不是问题。锁通常用于防止其他线程进行并发状态更改。
所以我不需要考虑死锁?
是的,你有。
线程不会对自身进行死锁(如果锁是可重入的)。但是,如果存在其他线程可能对您尝试锁定的对象具有锁定,则可能会出现死锁。
想象一下这样的事情:
function A():
lock (X)
B()
unlock (X)
function B():
A()
现在我们称之为A。将发生以下情况:
由于我们从未退出 A 的第一次调用,因此 X 仍处于锁定状态。这称为重新进入 - 当函数 A 尚未返回时,再次调用函数 A。如果 A 依赖于某个全局静态状态,这可能会导致“重新进入 bug”,在从函数的退出中清理静态状态之前,函数将再次运行,并且计算的一半值与第二次调用的开始发生冲突。
在这种情况下,我们遇到了一个我们已经持有的锁。如果锁是重新进入感知的,它将意识到我们已经是持有锁的同一根线,并让我们通过。否则,它将永远死锁 - 它将等待它已经持有的锁。
在java中,并且是可重新进入的 - 如果一个锁被一个线程持有,并且该线程试图重新获取相同的锁,则允许它。因此,如果我们用Java编写上述伪代码,它不会死锁。lock
synchronized