死锁的模拟

要想模拟死锁就要知道死锁的产生原因和条件,先看一下死锁的产生条件

死锁产生的必要条件:

1、 互斥使用:  既当资源被一个线程使用(占有)时,别的线程不能使用
2、 不可抢占:   资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有着主动释放
3、 请求和保持:  即当资源请求者在请求其他的资源的同时保持对原有资源的占有
4、 循环等待:  既当存在一个等待循环序列:p1要p2的资源,p2要p1的资源。这就形成了一个等待环路

概念分析:

如图:

在这里插入图片描述
模仿现实生活中的生产者-消费者问题,消费者有资金但是没有货源,而生产者有货源却没有资金。

有人会说生产者给消费者提供货源,消费者为生产者提供资金不就不会出现死锁了吗,答案是那肯定是呀,但是问题出在哪里?

死锁产生的必要条件有一个不满足就不会发生死锁

用上图来解释一下:

互斥使用 生产者占有了资金,但是却没有货源。消费者占有货源,而没有资金

请求和保持 消费者在需要货源时,不愿意先提供资金给生产者。而生产者在没获得资金时也不愿意先发货给生产者

例如,你在某宝买东西要求货到付款,而卖家要求你先付款后发货,到最后这笔交易就不会发生

不可抢占:生产者不能把消费者的货源给抢了,同理消费者也不能把生产者的资金抢了。

循环等待 生产者要消费者的货源,消费者要生产者的资金

死锁使我们在开发中一定一定要避免的,但是我们要明白它的原理,在面试的时候用的特别多

用代码演示死锁:

public class Test_死锁案例 {
	//创建两个锁对象,模拟资金和货源
	public static Object o1 = new Object();
	public static Object o2 = new Object();
	public static void main(String[] args) {
		//创建线程1
		new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (o1) {
					System.out.println(Thread.currentThread().getName()+"占用资源1,请求资源2");
					try {
					//休眠,让另一个线程抢占cpu,加大产生死锁的概率
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					synchronized (o2) {
						System.out.println(Thread.currentThread().getName()+"占用资源2,请求资源1");
					}
				}
			}
		}).start();

		//创建线程2
		new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (o2) {
					System.out.println(Thread.currentThread().getName()+"占用资源2,请求资源1");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					synchronized (o1) {
						System.out.println(Thread.currentThread().getName()+"占用资源1,请求资源2");
					}
				}
			}
		}).start();
		
	}
}
/*死锁发生的原因:当两个线程被执行时,假如线程1优先获得了cpu的使用权,此时它会获得o1的锁对象。
 * 获得锁对象后,它休息了1秒钟,此时线程2夺取到了cpu的使用权,线程2获得了o2的锁对象,在接下来的
 * 执行中,不管哪个线程获得了cpu的使用权,它需要的锁对象都被另一个线程所占有。因此出现了死锁。
 * 
 * */
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值