23.重入锁死(Reentrance Lockout)

重入锁死是跟死锁嵌套的监控程序锁死相似的一个场景。重入锁死也在读写锁中提到过了。

重入锁死可能会发生在如果一个线程重入一个锁中,ReadWriteLock或者一些其他的同步器不是可重入的。可重入的意味着已经持有一个锁的线程可以再一次持有它。Java的同步块是可重入的,因此下面的代码将会没有问题的工作:

public class Reentrant{

  public synchronized outer(){
    inner();
  }

  public synchronized inner(){
    //do something
  }
}

注意这个outer方法和inner方法是怎么被声明为同步方法的,这个跟Java中的synchronized(this)块是一样的。如果一个线程调用outer方法,然后在outer方法的内部调用inner方法是没有问题的,因为这两个方法(或者块)是在相同的监控对象上(“this”)同步的。如果一个线程在一个监控的对象上已经持有了一个锁,它可以访问相同监控对象上的所有的同步锁。这个称之为重入。这个线程可以重入它已经持有锁的任何一个代码块。

下面的这个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方法的第二次调用将会锁住。一个可重入的锁死就会发生了。

对于重入锁死你有两个选择:

  1. 避免写重入锁的代码。
  2. 使用重入锁。

这些选择具体哪个适合依赖你的具体场景。重入锁经常不会作为一个非重入锁执行,并且他们很难去实现,但是这个在你的场景中可能不是一个问题。你的代码是否简单的实现重入锁或者非可重入锁,这个得具体情况具体分析。

翻译地址:http://tutorials.jenkov.com/java-concurrency/reentrance-lockout.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值