7.18 线程:可重入锁

线程:可重入锁

简介

      锁作为并发共享数据保证一致性的工具,大多数内置锁都是可重入的,也就是说,如果某个线程试图获取一个已经由它自己持有的锁时,那么这个请求会立刻成功,并且会将这个锁的计数值加1,而当线程退出同步代码时,计数器将会递减,当计数值等于0时,锁释放。如果没有可重入锁的支持,在第二次企图获得锁时将会进入死锁状态。
      Java中提供可重入锁类:ReentrantLock。

测试

  1. 正常使用时的可重入锁
    code:
/**
 * 可重入锁测试
 * @author dxt
 *
 */
public class LockTest {
	public void test(){
		//第一次获得锁
		synchronized(this){
			while(true){
				//第二次获取锁,如果不可重入,则会死锁
				synchronized(this){
					System.out.println("可重入锁");
				}
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void main(String[] args){
		new LockTest().test();
	}
}
  1. 实现不可冲入锁
/**
 * 实现不可重入锁:锁不可以延续使用
 * @author dxt
 *
 */
public class LockTest02 {
	Lock lock = new Lock();
	
	public void a(){
		lock.lock();	//第一重锁
		b();
		lock.unlock();
	}
	public void b(){
		lock.lock();	//第二重锁。会产生死锁
		System.out.println("b");
		lock.unlock();
	}
	public static void main(String[] args){
		LockTest02 lt = new LockTest02();
		lt.a();		//死锁,程序会一直等待
	}
}
/**
 * 不可重用锁
 * @author dxt
 *
 */
class Lock{
	//是否占用
	private boolean isLocked = false;
	//使用锁
	public synchronized void lock(){
		//被加锁后,不能使用,只好等待
		while(isLocked){
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		isLocked = true;	//如果能访问到它,就加上锁,用完之前不释放
	}
	//释放锁
	public synchronized void unlock(){
		isLocked = false;
		notifyAll();
	}
}
  1. 实现可重入锁:锁可以连续且有计数器
/**
 * 实现可重入锁
 * @author dxt
 *
 */
public class LockTest03 {
	ReLock relock = new ReLock();
	
	public void a(){
		relock.lock();	//第一重锁
		b();
		relock.unlock();
	}
	public void b(){
		relock.lock();	//第二重锁。会产生死锁
		System.out.println("b");	//一些操作
		relock.unlock();
	}
	public static void main(String[] args){
		LockTest03 lt = new LockTest03();
		lt.a();		//死锁,程序会一直等待
	}
}
/**
 * 不可重用锁
 * @author dxt
 *
 */
class ReLock{
	//是否占用
	private boolean isLocked = false;
	Thread lockedBy = null;	//存储线程
	private int holdCount = 0;
	//使用锁
	public synchronized void lock(){
		//被加锁后,不能使用,只好等待
		Thread t = Thread.currentThread();
		while(isLocked && lockedBy != t){
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		isLocked = true;	//如果能访问到它,就加上锁,用完之前不释放
		lockedBy = t;
		holdCount++;
		//在lock()后可以对临界资源进行处理
	}
	//释放锁
	public synchronized void unlock(){
		if(Thread.currentThread() == lockedBy){
			holdCount--;
			if(holdCount == 0){
				isLocked = false;
				notifyAll();
				lockedBy = null;
			}
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值