java并发编程死锁定义及如何避免死锁

 更新时间:2022年02月09日 10:47:42   作者:Alpinist Wang  
这篇文章主要为大家介绍了java并发编程中死锁的详细说明及如何避免死锁的方法,有需要的朋友可以借鉴参考下希望能够有所帮助,祝大家多多进步

场景模拟分析

场景一:狭路相逢

在星期天的早上十点半,你在公路上开着车,这是一条窄路,只能容纳一辆车。这时,迎面又驶来一辆车,你们都走到一半,谁也不想倒回去,于是各不相让。陷入无尽的等待。

场景二:冷战

你和她吵架了,谁也不理谁,甚至晚饭时间都各自煮饭。你在炒京酱肉丝,她在做葱烤鲫鱼。炒到一半你发现小葱被她全部拿走了,于是你默默等待她做好菜后再去拿。殊不知她也在等待你炒完菜后来拿酱油。

场景三:哲学家就餐

你和四个好朋友坐在圆形餐桌旁,你们只做两件事情:吃饭,或者思考。吃饭的时候,你们就停止思考。思考的时候,也停止吃饭。每个人面前有一碗兰州炒饭。并且每个人左右两边各有一根筷子。你们必须要拿到两根筷子才能开始吃饭。吃完后再放下筷子,让别人可以使用。吃了一会之后,每个人都拿起了自己左手边的筷子,导致每个人都只有一根筷子,并且等待别人吃完放下筷子给自己。可惜,没有人吃到饭,所以没有人会放下筷子。(著名的哲学家就餐问题)

场景四:竞争资源

你有两个线程 A 和 B ,各自在加锁的状态下运行。 A 持有一部分资源,并且等待 B 线程中的资源以完成自己的工作,而此时 B 线程也在等待 A 中的资源以完成自己的工作。由于他们都是锁定状态,所以他们必须完成了自己的工作后,自己持有的资源才能释放。于是线程无休止的等待,导致死锁。

死锁是什么?

上述四个场景都是程序员在工作或生活中会遇到的问题,人生就像是一个进程,时间是我们的主线程,期间做的每一件事都是开启的一个子线程。当多件事冲突时,并发问题就产生了。以上场景都指向同一类并发问题:死锁。

当两个以上的运算单元,双方都在等待对方停止运行,以获取系统资源,但是没有一方提前退出时,就称为死锁。

产生死锁的的四个条件如下:

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

2、请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放;

3、不剥夺条件:进程已获得的资源,在没使用完之前,不能强行剥夺;

4、循环等待条件:多个进程之间形成一种互相循环等待资源的关系。

并发带来压力,有的人或有的程序,会因为承受不住压力而崩溃,情绪崩溃和程序崩溃没什么两样。当然,不论是做人还是写程序,面对问题时,正确的做法都应是采取策略,解除死锁。

如何避免死锁?

死锁一旦发生,便无法解除。我们能做的只能尽量避免死锁。要避免死锁,只需破坏产生死锁的四个条件之一即可。

方案一:破坏不剥夺条件

你想起书中所言:退一步海阔天空。但你也深知公平好过忍让。正值周赛时间,你摇下车窗,对对面的兄弟喊道:咱来比赛一场力扣周赛,谁输了谁倒出去让另一个人过吧!于是你们打开力扣,开始答题。半小时后,你凭借高超的代码水平 AC 了全部题目。对面司机对你拱手道:技不如人,甘拜下风。于是他倒了回去,让出了自己的一半路。最终你们都得以顺利通行。

破坏不剥夺条件:让对面的司机放弃了自己已有的资源。

方案二:破坏请求与保持条件

你在炒菜时发现没有小葱,于是你换位思考,想到她会不会也缺少自己用着的材料。虽然她还在和你冷战,但你劝解自己一个大老爷们不应该和女孩子置气,于是你主动把自己用着的所有材料拿给了她。她感受到你设身处地为她着想,大为感动,你们和好如初。之后她为你们两个人一起炒了京酱肉丝和葱烤鲫鱼。

破坏请求与保持条件:在自己需要的材料缺少时,主动放弃自己持有的资源,防止出现互相等待。

方案三:破坏循环等待条件

你和你的朋友们决定给筷子编上号:1~5。规定每个人拿筷子时必须先拿到自己两边的筷子中号码小的那一根,再去拿号码大的那一根。如果小的那一根没有拿到,不能先拿大的。当你们开始吃饭时,由于数字 5 不可能被一个人单独拿到。因为他旁边的另一根筷子编号必定比 5 小,所以不会再出现每个人都拿着一根的无限等待情形。

破坏循环等待条件:由于筷子指定了编号和获取规则,所以每个锁定状态都将按照顺序执行,于是便杜绝了环路等待条件。

方案四:破坏互斥条件

你在运行两个线程前,预先将线程 A 和 B 中的资源拷贝一份,让他们不需互相等待对方的资源,于是两个线程都得以顺利运行。

破坏互斥条件:由于每次使用时都拷贝一份,所以一个资源可以被多个进程使用。

以上就是java并发编程死锁定义及如何避免死锁的详细内容,更多关于java死锁及避免的资料请关注脚本之家其它相关文章!

相关文章

  • 使用javaMail实现发送邮件

    使用javaMail实现发送邮件

    这篇文章主要为大家详细介绍了使用javaMail实现发送邮件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • Java实现给微信群中定时推送消息

    Java实现给微信群中定时推送消息

    这篇文章主要为大家详细介绍了Java如何实现给微信群中定时推送消息的功能,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以了解一下
    2022-12-12
  • 如何在 Java 中实现不可变类

    如何在 Java 中实现不可变类

    这篇文章主要介绍了如何在 Java 中实现不可变类,不变性是函数式编程的关键,因为它与尽量减少变化部分的这一目标相一致,这使得对这些部分的推断更为容易一些。,需要的朋友可以参考下
    2019-06-06
  • springcloud feign服务之间调用,date类型转换错误的问题

    springcloud feign服务之间调用,date类型转换错误的问题

    这篇文章主要介绍了springcloud feign服务之间调用,date类型转换错误的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Java高性能本地缓存框架Caffeine的实现

    Java高性能本地缓存框架Caffeine的实现

    本文主要介绍了Java高性能本地缓存框架Caffeine的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Spring Boot Web 开发注解篇

    Spring Boot Web 开发注解篇

    在 Spring Boot 快速入门中,只要在 pom.xml 加入了 spring-boot-starter-web 依赖,即可快速开发 web 应用。下文给大家详细介绍了spring boot web 开发注解,感兴趣的朋友参考下吧
    2017-08-08
  • 在SpringBoot中通过jasypt进行加密解密的方法

    在SpringBoot中通过jasypt进行加密解密的方法

    今天小编就为大家分享一篇关于在SpringBoot中通过jasypt进行加密解密的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • JAVA返回PDF文件流并进行下载的实现方法

    JAVA返回PDF文件流并进行下载的实现方法

    这篇文章主要给大家介绍了关于JAVA返回PDF文件流并进行下载的实现方法,PDF文件流下载是通过HTTP协议将服务器上的PDF文件以流的方式发送给客户端,供客户端保存到本地磁盘或直接在浏览器中打开,需要的朋友可以参考下
    2024-02-02
  • 浅谈序列化之protobuf与avro对比(Java)

    浅谈序列化之protobuf与avro对比(Java)

    下面小编就为大家带来一篇浅谈序列化之protobuf与avro对比(Java)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • springboot自动装配的源码与流程图

    springboot自动装配的源码与流程图

    在日常的开发过程中Spring Boot自动装配的特性给我们开发减少了很多重复性的工作,这篇文章主要给大家介绍了关于springboot自动装配的相关资料,需要的朋友可以参考下
    2021-08-08

最新评论