Java多线程——重进入(Reentrancy)机制

       当一个线程请求其他线程已经占有的锁是,请求线程将被阻塞。然后内部锁是可重进入的,因此线程在试图获得它自己占有的锁时,请求会成功。重进入意味着Java的请求是基于“每线程(per-thread)”,而不是基于“没调用(per-invocation)”的。重进入的实现是通过为每个锁关联一个请求计数(acquisition count)和一个占有它的线程。当计数为0时,认为锁是未被占有的。线程请求一个未被占有的锁时,JVM将记录锁的占有者,并且将请求计数置为1。如果同一线程再次请求这个锁,计数将递增;每次占用线程退出同步块,计数器值将递减。直到计数器达到0时,锁被释放。

public class Widget {
       public synchronized void doSomething(){
               ...... 
      }
}

public class LoggingWidget extends Widget{
      public synchronized void doSomething(){
             System.out.println(toString() + ": calling doSomething");
             super.doSomething();
     }
}

        重进入方便了锁行为的封装,因此简化了面向对象并发代码的开发。上面代码中,子类覆写了父类synchronized类型的方法,并调用父类中的方法。如果没有可重入的锁,这段看上去很自然的代码就会产生死锁。因为Widget和LoggingWidget中的doSomething方法都是synchronized类型的,都会在处理前试图获得Widget的锁。倘若内部锁不是可重入的,super.doSomething的调用者就永远无法得到Widget的锁,因为锁已经被占有,导致线程永久地延迟,等待着一个永远无法获得的锁。重进入帮助我们避免了这种死锁。

转载于:https://my.oschina.net/czg/blog/142681

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值