什么是死锁,如何解决

一、死锁的定义

  • 死锁是指在执行过程中,两个或两个以上的进程(或线程)由于竞争资源或彼此通信而阻塞,导致无法继续执行的情况。

  • 如果没有外部干预,这些进程将无法向前推进。

  • 这种状态被称为系统死锁或死锁产生。

  • 这些相互等待的进程被称为死锁进程。

死锁案例:

🕵️‍♀️面试官:🕵️‍♀️

你给我讲清楚死锁,我就录用你

🐱‍🚀面试者:🐱‍🚀

你录用我,我就给你讲清楚

二、产生死锁的四个必要条件

1. 互斥条件: 一个资源每次只能被一个进程使用

  1. 在并发执行的多个事务中,产生死锁的一个重要条件是互斥条件。互斥条件指的是某个资源一次只能被一个事务持有,其他事务必须等待该资源释放才能获取到。

  2. 互斥条件在死锁产生中起到关键作用,它确保了资源的独占性。当一个事务获得了资源A的锁,其他事务就无法同时获得资源A的访问权限,只能等待该事务释放资源A的锁。如果同时有另一个事务持有资源B的锁,并且尝试获取资源A的锁,就会发生死锁。

  3. 简单来说,互斥条件是指每个资源只能被一个事务持有,其他事务必须等待所需资源的释放。

2. 占有且等待:一个进程因请求资源而阻塞时,对已获得的资源保持不放

  1. 在并发执行的多个事务中,产生死锁的另一个重要条件是"占有且等待"。"占有且等待"指的是一个事务在持有某个资源的同时,又等待其他事务所占有的资源。

  2. 具体来说,当一个事务获得了某个资源的锁,并且在持有该资源的同时,还需要获取其他事务所占有的资源,但该资源又被其他事务持有时,就会产生"占有且等待"的情况。当多个事务相互等待对方所占有的资源时,就可能发生死锁。

  3. "占有且等待"条件是死锁产生的一个关键因素。当事务之间存在资源依赖关系,且每个事务只释放部分资源而不是一次性释放所有资源时,就容易出现"占有且等待"的情况。如果没有适当的资源管理策略,就有可能导致死锁的发生。

3. 不可强行占有: 进程已获得的资源,在末使用完之前,不能强行剥夺。

  1. 在并发执行的多个事务中,产生死锁的另一个重要条件是"不可强行占有"。不可强行占有指的是一个事务在持有某个资源的同时,又不允许其他事务强行抢占该资源。

  2. 具体来说,当一个事务获得了某个资源的锁,并且在持有该资源的同时,不可被其他事务强制释放该资源,就会产生"不可强行占有"的情况。当多个事务同时持有某个资源,并且互相等待对方释放资源时,就可能发生死锁。

  3. "不可强行占有"条件是死锁产生的另一个关键因素。当事务之间存在资源竞争关系,且每个事务不能被强制释放所占有的资源时,就容易出现"不可强行占有"的情况。如果没有适当的资源管理策略,就有可能导致死锁的发生。

4. 循环等待条件: 若干进程之间形成一种头尾相接的循环等待资源关系

  1. 在并发执行的多个事务中,产生死锁的另一个重要条件是"循环等待"。循环等待指的是多个事务之间形成了一个闭环,每个事务都在等待下一个事务所占有的资源。

  2. 具体来说,当多个事务之间存在资源依赖关系,并且这些事务形成了一个环路,每个事务都在等待下一个事务所占有的资源时,就会产生"循环等待"的情况。这样,每个事务都无法继续执行,导致系统无法进一步进行,即产生死锁。

  3. 循环等待条件是死锁产生的另一个关键因素。当事务之间存在循环依赖关系,且每个事务都在等待下一个事务所占有的资源时,就容易出现循环等待的情况。如果没有适当的资源分配和调度策略,就有可能导致死锁的发生。

三、如何解除死锁

🎯为了解除和预防死锁,可以从以下几个方面入手:🎯

  • 破坏不可抢占:通过设置优先级,使优先级高的进程能够抢占资源。

  • 破坏循环等待:保证多个进程(线程)的执行顺序相同,从而避免循环等待。例如,如果执行顺序是A -> B -> C,那么就可以避免循环等待。

  • 最常用的避免方法是破坏循环等待,即确保多个事务的执行顺序相同。

  • 例如,事务1执行顺序为A -> B -> C,事务2执行顺序为C -> D -> A,这种情况可能导致死锁。因为事务1占有了A并等待C,而事务2占有了C并等待A。因此,为了避免死锁,可以将事务2的执行顺序改为A -> D -> C。

四、数据库死锁

1. 死锁原因:

  • 在数据库中,当多个事务并发执行时,也可能发生死锁。

  • 例如,事务1持有资源A的锁,并尝试获取资源B的锁,而事务2持有资源B的锁,并尝试获取资源A的锁。

  • 在这种情况下,就会发生死锁。

  • 当发生死锁时,系统会产生异常,指示发生了死锁情况。

2. 不同数据库死锁报错情况:

在数据库中,当发生死锁时,通常会报错并提供相应的错误信息。

✨具体的错误信息可能因数据库系统而异,以下是一些常见的错误信息示例:✨

2.1. Oracle数据库:

ORA-00060: deadlock detected while waiting for resource

2.2. MySQL数据库:

Deadlock found when trying to get lock; try restarting transaction

这些错误信息表明发生了死锁,并提醒用户或开发者重新运行事务或采取适当的措施来解决死锁问题。

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
是指两个或多个进程在互斥地请求资源的时候,由于资源被占用而无法继续执行,导致所有进程都被阻塞的情况。在Spring Boot中,可能发生在多线程并发访问共享资源时,例如数据库连接池、缓存、等。 在给出解决方案之前,我们需要先排查问题。一种常用的排查问题的方法是使用jstack命令输出线程的堆栈信息。通过查看堆栈信息,我们可以定位到可能引起的代码行,并进行解决修复。 下面是一个示例代码,模拟了一个可能导致的场景: ```java package com.xz.springboottest.day1; public class DeadLock { private static final String ACTION_ONE = "拿起碗"; private static final String ACTION_TWO = "拿起筷子"; public static void main(String[] args) { // 哲学家小明 new Thread(() -> { synchronized (ACTION_ONE) { try { Thread.sleep(1000); synchronized (ACTION_TWO) { System.out.println("小明开始吃饭了。。。。。。"); } } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); // 哲学家小张 new Thread(() -> { synchronized (ACTION_TWO) { try { Thread.sleep(1000); synchronized (ACTION_ONE) { System.out.println("小张开始吃饭了。。。。。。"); } } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } } ``` 以上代码模拟了哲学家就餐的场景,当只剩下一只碗和一双筷子时,可能出现的问题。 对于解决的方法,可以考虑以下几种方案: 1. 避免循环等待:为了避免,可以规定所有线程在请求资源时按照固定的顺序获取,从而避免循环等待。 2. 加顺序:在多个线程同时请求多个资源的情况下,为了避免,可以约定线程必须按照相同的顺序请求资源。 3. 设置超时时间:在获取的时候设置超时时间,如果超过一定时间还未获取到,可以放弃或者重试。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Run,boy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值