在JAVA中,内置锁都是可重入的,也就是说,如果某个线程试图获取一个已经由它自己持有的锁时,那么这个请求会立刻成功,并且会将这个锁的计数值加1,而当线程退出同步代码块时,计数器将会递减,当计数值等于0时,锁释放。
new Thread() {
@Override
public void run() {
// 第一次获得锁
synchronized(this) {
while(true) {
// 第二次获得同样的锁
synchronized(this) {
System.out.println("ReteenLock!");
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}.start();
如果没有可重入锁的支持,在第二次企图获得锁时将会进入死锁状态。在实际的代码中,我们可能不会这么写代码,但是可重入锁依旧随处可见,如下:
public class PartBuilder {
public synchronized void swim() {
}
public synchronized void fly() {
}
/**
* 可重入锁
*/
public synchronized void buildPart() {
this.swim();
this.fly();
}
}
在上面的例子中,进入swim()方法时已经获取了对象锁,在调用fly()时又再次获取对象锁,此时对象的锁计数值已经达到2了。
JAVA的可重入锁提升了加锁行为的封装性,大大简化了面向对象并发代码开发的难度。