可重入意味着在每个线程而不是每次调用的基础上获取锁.
由于线程持有内部锁,这不意味着线程运行一次等于调用基础吗?
谢谢,似乎意味着:在一个线程中,如果我lockA在doA调用函数的过程函数中得到一个锁doB,并且doB还需要一个锁lockA,那么就会有一个可重入.在Java中,每个线程都会获得这种现象,所以我不需要考虑死锁?
Ste*_*n C 63
可重入意味着在每个线程而不是每次调用的基础上获取锁.
这是一个误导性的定义.这是真的(有点),但它忽略了真正的观点.
可重入意味着(通常是CS/IT术语)你做了什么,当你还在做的时候,你再做一次.在锁的情况下,它意味着您在单个线程上执行类似的操作:
使用可重入锁定/锁定机制,获取相同锁定的尝试将成功,并将增加属于锁定的内部计数器.只有当锁的当前支架已经释放两次时,锁才会被释放.
这是Java中使用原始对象锁/监视器的一个例子......它们是可重入的:
Object lock = new Object();
...
synchronized (lock) {
...
doSomething(lock, ...)
...
}
public void doSomething(Object lock, ...) {
synchronized (lock) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
可重入的替代方法是非重入锁定,其中线程尝试获取已经存在的锁定将是错误的.
使用重入锁的优点是您不必担心由于意外获取已经存在的锁而导致失败的可能性.缺点是您无法假设您调用的任何内容都不会更改锁定旨在保护的变量的状态.但是,这通常不是问题.锁通常用于防止其他线程发生的并发状态更改.
所以我不需要考虑死锁?
是的你是.
线程不会对自身死锁(如果锁是可重入的).但是,如果有其他线程可能锁定您要锁定的对象,则可能会出现死锁.
Pat*_*shu 16
想象一下这样的事情:
function A():
lock (X)
B()
unlock (X)
function B():
A()
Run Code Online (Sandbox Code Playgroud)
现在我们打电话给A.以下情况发生:
由于我们从未退出A的第一次调用,因此X仍然被锁定.这称为重入 - 当函数A尚未返回时,再次调用函数A. 如果A依赖于某种全局静态状态,这可能会导致"重新进入错误",在从函数出口清除静态状态之前,该函数再次运行,并且半计算值与启动时相撞第二个电话.
在这种情况下,我们遇到了一个我们已经持有的锁.如果锁是重新进入的意识,它将意识到我们是同一个持有锁的线程并让我们通过.否则,它将永远死锁 - 它将等待它已经存在的锁定.
在java中,lock并且synchronized是重新进入的 - 如果线程持有锁,并且线程试图重新获取相同的锁,则允许它.因此,如果我们用Java编写上述伪代码,它就不会死锁.
实践中的Java并发书状态 - Reentrancy means that locks are acquired on a per-thread rather than per-invocation basis.
让我解释它究竟意味着什么.首先,内在锁本质上是可重入的.实现重入的方式是通过维护所获得的锁的数量和锁的所有者的计数器.如果计数为0且没有所有者与之关联,则表示任何线程都不保留锁定.当线程获取锁时,JVM记录所有者并将计数器设置为1.如果同一线程再次尝试获取锁,则计数器递增,并且当拥有线程存在时,同步块计数器递减.当计数达到0时,锁定被释放.
一个简单的例子是 -
public class Test {
public synchronized void performTest() {
//...
}
}
public class CustomTest extends Test {
public synchronized void performTest() {
//...
super.performTest();
}
}
Run Code Online (Sandbox Code Playgroud)
没有重入就会出现僵局.