Reentrance Lockout的状况相似于死锁和nested monitor lockout.Reentrance Lockout在先前的Java中的锁和Java中的读写锁两篇文章中都有提到.html
线程在屡次获取锁和读写锁实例或是其余不支持可重入的同步机制时会陷入阻塞即锁死.可重入意味着线程能够屡次持有同一把锁.Javasynchronized
同步块是可重入的.下面给出可重入的示例代码:java
public class Reentrant{
public synchronized void outer() {
inner();
}
public synchronized void inner() {
// do something you like
}
}
复制代码
咱们能够注意到outer()和inner()方法签名中都有synchronized
声明,这在Java中等同于synchronized(this)
同步代码块。当多个方法都是以"this"即当前对象做为监控对象时,那么一个线程在调用完outer()方法后,天然能够在outer()方法内部调用inner()方法。一个线程将一个对象做为监控对象即取得该对象锁后,它能够进入其余使用相同对象做为对象锁的同步代码块。这种状况咱们称之为可重入。线程能够反复进入它所取得监控对象的所有同步代码块。post
在以往文章总提到过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();
}
}
复制代码
若是一个线程在没有调用unlock()的状况下,两次掉调用lock()方法,那么它将阻塞在第二次lock()方法调用上.这时候reentrance lockout 就会发生了.this
面对这种状况咱们有两种选择:spa
你应该根据实际状况来选择.可重入锁须要提供额外的功能来支持可重入性,所以一般会比不可重入锁性能要稍差点.还有可重入锁一般比较难实现,但幸亏Java已经提供了相应的实现了.不管你的代码实现可重入性如何你都须要谨慎使用可重入锁.线程
该系列博文为笔者复习基础所著译文或理解后的产物,复习原文来自Jakob Jenkov所著Java Concurrency and Multithreading Tutorial code