锁的可重入性(Reentrant)

本文深入探讨了可重入锁的概念及其在Java中的应用。详细解释了锁的可重入性如何防止死锁,特别是在方法递归调用的场景下。通过示例代码展示了synchronized关键字和ReentrantLock类的使用,强调了锁的正确释放对于避免死锁的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 可重入锁的定义

public synchronized void test(){ 
    //business 
    test1(); 
}
 
public synchronized void test1(){ 
    //business 
}

在上段代码中,执行test方法需要获取当前对象的监视器锁,而test方法内部又调用了同步方法test1。

如果对象监视器锁是具有可重入性的,那么该线程在调用test1时,可以再次或的对象的监视器锁,从而进入test1方法。

如果对象监视器锁不具有可重入性,那么线程在test方法中调用同步方法test1之前,需要等待当前对象监视器锁的释放,然而,实际上该对象的监视器锁已经被当前线程所持有,不可能再次获得,死锁产生。

综上,锁的可重入性就是一个线程在已经持有锁的情况下,能否再次获取这把锁。

所以,如果有方法的递归调用发生,方法中的锁必须是可重入锁,否则会造成死锁的发生。

BTW,对象监视器锁是可重入锁,所以上面的代码能够正产执行。

 

2. 可重入锁的使用

同一个可重入锁,被同一线程锁了几次,就需要释放几次。

a) Synchronized修饰的对象监视器锁,在临界区(同步块/同步方法)自动锁定和解锁。

b) ReentrantLock这种显式锁,需要手动释放。

		if(reentrantLock.tryLock()){
			String currentThreadName = Thread.currentThread().getName();
			try {
				System.out.println(currentThreadName + " get reentrantLock....");
				Thread.sleep(100);
			} catch (InterruptedException e) {
				System.out.println(currentThreadName + " is interrupted....");
			} finally{
				System.out.println(currentThreadName + " release reentrantLock....");
				reentrantLock.unlock();
			}
		}else{
			System.out.println(Thread.currentThread().getName() + " is waiting for lock release....");
			this.reentrantLock.lock();
			this.run();//do the business
			System.out.println(Thread.currentThread().getName() + " release reentrantLock");
			this.reentrantLock.unlock();//when using ReentrantLock, recursion lock need recursion unlock
		}

 

转载于:https://my.oschina.net/mose/blog/681969

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值