文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

死锁(JAVA)

2023-12-22 21:48

关注

死锁在多线程代码中是非常严重的BUG,一旦代码中出现死锁就会导致线程卡死。
单个线程连续两次同一个对象进行加锁操作时,如果该锁是不可重入锁就会发生死锁(线程卡死)

两个线程两把锁,如果出现这种情况也是会发生死锁:线程t1已经获取了锁A,线程t2已经获取了锁B,此时t1想要获取锁B,t2想要获取锁A。

Object lock1 = new Object();Object lock2 = new Object(); Thread t1 = new Thread(()->{    synchronized(lock1) {        try {            Thread.sleep(1000);        } catch (InterruptedException e) {            throw new RuntimeException(e);        }        synchronized(lock2) {         }    }});Thread t2 = new Thread(()->{    synchronized(lock2) {        try {            Thread.sleep(1000);        } catch (InterruptedException e) {            throw new RuntimeException(e);        }        synchronized(lock1) {         }    }});t1.start();t2.start();//让主线程等待 2 秒Thread.sleep(2000);//此时t1和t2两个线程会因为互相争对方的锁,而导致死锁System.out.println(t1.getState());System.out.println(t2.getState());

在这里插入图片描述

如果此时有N个线程M把锁(N,M>>2),就更加容易发生死锁的情况了。

一个非常经典的N个线程M把锁的问题:哲学家就餐问题。

假设有5名哲学家围在一张桌子上吃面,现在桌子上有5根筷子。(哲学家会做两件事:思考和吃面(吃面必须要拿到两根筷子,吃完后会将筷子放回原处)。且做这两件事的时间是完全随机的,同一时间只能做一件事)
在这里插入图片描述
大多数情况下是不会出现问题的但也会出现一些极端情况:现在所有的哲学家都想吃面,他们同时拿起了自己左手边的筷子,此时每位哲学家手里都有且仅有一只筷子,此时每位哲学家都在等待另一支筷子就会发生死锁。
那么该如何解决死锁问题呢?首先我们先要了解死锁的必要条件,然后根据这些条件来修改。

引发死锁的必要条件

  1. 互斥(锁的基本特性);当一个线程获取到锁后,如果另一个线程也想获取该锁就会阻塞等待。
  2. 不可抢占(锁的基本特性);当线程A获取到锁后,如果线程B也想获取该锁只能等待A将该锁释放后再获取,不能直接抢。
  3. 请求保持(代码结构);一个线程获取了A锁后继续获取B锁……且前面获取的锁不进行释放。
  4. 循环等待/环路等待(代码结构);等待的依赖关系形成了环。

一个死锁代码一定会满足上述四种情况,任意一个不满足都不会形成死锁。

死锁的解决方法

解决死锁的情况只要破坏上述条件中的任意一个就行了。
上述四条中1和2都是锁的基本特性,所以无法改变。
对于3,在代码中尽量避免出现锁嵌套的情况,但是这种情况很难避免,因为实际代码中的嵌套往往都是这样的,很难发现和避免:

public void fun1(){    synchronized (this) {        fun2();    }}public void fun2(){    fun3();}public void fun3(){    fun4();}public void fun4(){    synchronized (this) {    }}

所以解决4就显得非常重要了,那么4这种情况该如何避免呢?
有一个非常简单的方法那就是约定加锁的顺序。
例如对于上文中的哲学家就餐的问题:
现在给每支筷子进行编号,约定每位哲学家拿筷子的顺序都是必须先拿面前编号较小的然后再拿编号较大的。
在这里插入图片描述
B拿1号筷子->C拿2号筷子->D拿3号筷子->E拿4号筷子->A拿1号筷子但是1号筷子此时在B手中所以A会阻塞等待,此时E拿到5号筷子吃完后放下筷子->D拿到4号筷子吃完后放下筷子->C拿到3号筷子吃完后放下筷子->B拿到2号筷子吃完后放下筷子。
此时就完美避免了死锁问题的发生。

来源地址:https://blog.csdn.net/2302_76339343/article/details/134352961

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯