如果synchronized是不可重入的,为什么重载父类函数后(重载函数也加锁)会产生死锁?

我们知道synchronized可以加在方法上也可以加在代码块上,其实加在方法上也相当于加载代码块上,好比这种形式:

synchronized(this){ 
  doSomething();
}
从这里可以看出,锁其实是基于对象的,是对当前访问的对象进行加锁,现在假设有如下两个类:

class Widget{
  synchronized doSomething(){
    .........................
  }
}
class LoggingWidget extends Widget
{
   @Override
   synchronized doSomething(){
     ..................
     super.doSomething();
   }
}


因为锁的是基于对象的,不管父类还是子类,如果你需要调用当前的方法,那么对用户这个方法而言他对应的都是同一个对象,因为是一个对象在调用这个方法,此时this关键字指向的就是这个对象,你可以想象子类现在是这样的:

class 
LoggingWidget {
@Override doSomething(){

	synchronized (this)
	{    
		............//Son类doSomething()中的操作   
	synchronized (this)
	{    
		 ............//Foo类doSomething()中的操作  
 	}  
	} 
    }
}
想象成上面这种形式的话,可以看到,到这里该对象的锁获需要获取两次,如果锁是不可重入的,那么第二次锁将获取不到,那么这个时候就会产生死锁。对象维持一个锁的计数器,进入锁加一,退出锁减一,如果为零则可以获取该锁。
换句话说就是,LoggingWidget实例对象调用doSomething方法时此时持有的是LoggingWidget实例对象的锁,之后调用super.doSomething,这时仍然对于LoggingWidget实例对象加锁,因为此时仍然使用的是LogginWidget实例对象内存空间中的数据。这也说明了内置例对象加锁,因为此时仍然使用的是LogginWidget实例对象内存空间中的数据。这也说明了内置锁重入的重要性,若不是重入的,那么当调用super.doSomething时,因为线程已经持有了LoggingWidget实例锁,再次请求持有LoggingWidget实例锁时,就会永远等待一个获取不到的锁


  
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值