Java concurrency <闭锁>
2018-06-16 本文已影响22人
熬夜的猫头鹰
Java concurrency <闭锁>
重入锁定是类似于死锁和嵌套监视器锁定的情况。 有关锁定和读取/写入锁定的文本部分也涉及重入锁定。
如果线程重新输入Lock,ReadWriteLock或其他不可重入的同步器,则可能会出现重入锁定。 可重入意味着已经持有锁的线程可以重新获取。 Java的同步块是可重入的。 因此,以下代码将无问题地工作:
public class Reentrant{
public synchronized outer(){
inner();
}
public synchronized inner(){
//do something
}
}
注意outer()和inner()如何被声明为synchronized,在Java中等同于一个synchronized(这个)块。 如果一个线程调用outer(),那么从outer()内部调用inner()没有问题,因为这两个方法(或块)都在同一个监视器对象(“this”)上同步。 如果一个线程已经拥有监视对象上的锁定,它可以访问同一个监视器对象上同步的所有块。 这叫做reentrance。 线程可以重新输入它已经保持锁定的任何代码块
以下Lock实现不可重入:
public class Lock{
private boolean isLocked = false;
public synchronized void lock()
throws InterruptedException{
while(isLocked){
wait();
}
isLocked = true;
}
public synchronized void unlock(){
isLocked = false;
notify();
}
}
如果一个线程调用lock()两次而不调用unlock(),那么第二次调用lock()就会被阻塞。 发生重入锁定。
为了避免重入锁定,您有两个选择:
- 避免编写重新锁定的代码
- 使用可重入锁
哪些选项适合您的项目最好取决于具体情况。 可重入锁通常不能执行非易失性锁,而且它们更难实现,但这可能不是您的情况下的问题。 您的代码是否更容易实现有或没有锁重入必须逐个确定。