死锁的成因以及解决方案(简析)

目录

一.为什么会产生死锁?

二.死锁产生的几个场景

一个线程一把锁的情况

关于可重入和不可重入锁的简单举例

两个线程两把锁的情况

多线程多把锁

 如何解决死锁


一.为什么会产生死锁?

简单来说,就是进程加锁之后,没有被解锁而处于一直等待的状态

二.死锁产生的几个场景

一个线程一把锁的情况

如果单个线程被连续加锁两次及以上,成为了不可重入锁,那么该线程就造成了死锁(一般的synchronized是可重入锁,不会造成死锁)

关于可重入和不可重入锁的简单举例

public class syn{
	public synchronized void do1(){
		System.out.println("执行1");
		do2();
	}
	public synchronized void do2(){
		System.out.println("执行2");
	}	
}

如果是不可重入锁,那么我们在执行完输出语句"执行1"之后,因为锁是任然在do1手中,没有释放,那么我们是不能执行do2(),这个语句的

但是如果是可重入锁,那么我们就能直接获取do2的锁,然后执行do2操作

两个线程两把锁的情况

线程一等待着线程二给自己释放锁,线程二等待着线程一给自己释放锁

多线程多把锁

经典案例:哲学家吃面

 总所周知,一般人吃面是需要两根筷子(用手抓就算了吧)

但是这里有五个哲学家(五把锁)对应着五个筷子(五个解锁)

如果出现一种比较极端的情况

大家都同时拿自己左手或者右手的筷子(同时都获取了一把锁)

那大家都吃不了(都解锁不了)

 所以总结一下,造成死锁的四个条件

1.互斥使用.锁A被线程1占用,线程2就用不了

2.不可抢占.锁A被线程1占用,线程2不能把锁A抢过来, 除非线程1主动释放锁

3.请求和保持.有多把锁,线程1拿到锁A后,不想释放锁A,还想拿到一个锁B

4.循环等待.线程1 等待 线程2释放锁,线程2 要释放锁得等待线程3 来释放锁,线程3 释放锁得等待线程1 释放锁

 如何解决死锁

一句话

破坏上诉四个条件的任意一个即可

但是条件一和条件二是锁的基本特性,没法改

条件三的话只要释放锁就行,但是在大多数场景下没办法直接释放

所以一般来说

我们都是破坏循环条件

对于上面的哲学家吃面的问题,我们就可以对筷子(锁)进行编号,控制哲学家们拿筷子的顺序,就能解决死锁

 教科书上一般采用银行家算法,但是现实中基本不太实用,有兴趣的同学自行了解本文不多赘述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值