「操作系统」深入理解死锁(什么是死锁?死锁形成条件?如何避免死锁?如何排查死锁?)

「操作系统」深入理解死锁(什么是死锁?死锁形成条件?如何避免死锁?如何排查死锁?)

参考&鸣谢

什么是线程死锁?形成条件是什么?如何避免? Java圈子

面试官:如何快速排查死锁?如何避免死锁? 阿风架构笔记

怎么避免死锁? XiaoLinCoding

文章目录

  • 「操作系统」深入理解死锁(什么是死锁?死锁形成条件?如何避免死锁?如何排查死锁?)
    • @[toc]
    • 一、什么是死锁
    • 二、死锁形成条件
      • 互斥条件
      • 持有并等待条件
      • 不可剥夺条件
      • 环路等待条件
    • 三、模拟死锁、排查死锁
    • 四、如何避免死锁
    • 五、小结

一、什么是死锁

死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程(线程)称为死锁进程(线程)。

多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

如下图所示,线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态。


二、死锁形成条件

互斥条件

互斥条件是指多个线程不能同时使用同一个资源

比如下图,如果线程 A 已经持有的资源,不能再同时被线程 B 持有,如果线程 B 请求获取线程 A 已经占用的资源,那线程 B 只能等待,直到线程 A 释放了资源。

「操作系统」深入理解死锁(什么是死锁?死锁形成条件?如何避免死锁?如何排查死锁?)_第1张图片

持有并等待条件

持有并等待条件是指,当线程 A 已经持有了资源 1,又想申请资源 2,而资源 2 已经被线程 C 持有了,所以线程 A 就会处于等待状态,但是线程 A 在等待资源 2 的同时并不会释放自己已经持有的资源 1

「操作系统」深入理解死锁(什么是死锁?死锁形成条件?如何避免死锁?如何排查死锁?)_第2张图片

不可剥夺条件

不可剥夺条件是指,当线程已经持有了资源 ,在自己使用完之前不能被其他线程获取,线程 B 如果也想使用此资源,则只能在线程 A 使用完并释放后才能获取。

「操作系统」深入理解死锁(什么是死锁?死锁形成条件?如何避免死锁?如何排查死锁?)_第3张图片

环路等待条件

环路等待条件指的是,在死锁发生的时候,两个线程获取资源的顺序构成了环形链

比如,线程 A 已经持有资源 2,而想请求资源 1, 线程 B 已经获取了资源 1,而想请求资源 2,这就形成资源请求等待的环形图。

「操作系统」深入理解死锁(什么是死锁?死锁形成条件?如何避免死锁?如何排查死锁?)_第4张图片


三、模拟死锁、排查死锁

详细请看我之前发布过的文章

「多线程锁」手写死锁案例及排查死锁原因

Jstack命令

jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息。 Jstack工具可以用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。

JConsole工具

Jconsole是JDK自带的监控工具,在JDK/bin目录下可以找到。它用于连接正在运行的本地或者远程的JVM,对运行在Java应用程序的资源消耗和性能进行监控,并画出大量的图表,提供强大的可视化界面。而且本身占用的服务器内存很小,甚至可以说几乎不消耗。


四、如何避免死锁

预防

  • 破坏互斥条件:使得多个进程可以同时访问同一个资源。例如,在内存中缓存某些资源,从而避免频繁的磁盘读写。
  • 破坏不可抢占条件:当一个进程所持有的资源被其它进程请求时,可以强制该进程放弃资源,或者等待它所持有的资源被释放后才能再次获取。
  • 破坏请求与保持条件:进程在申请新资源之前先释放它所拥有的所有资源,等待新资源的分配,再重新申请先前持有的资源。
  • 破坏循环等待条件:通过给资源编号,规定每个进程按编号的顺序请求资源,释放资源的顺序与请求的顺序相反,从而避免循环等待。
  • 合理地设置超时时间:如果一个进程不能在一定时间内获得所需的所有资源,就应该释放已经获取的资源,以免造成系统资源的浪费。

五、小结

死锁是多进程并发执行中的一种常见问题,它可以被解释为若干进程因为彼此竞争系统资源而导致陷入互相等待的一种僵局状态。为了避免死锁的发生,我们需要明确死锁发生的四个必要条件:互斥条件、不可抢占条件、请求与保持条件以及循环等待条件,并采取相应的策略和措施来破坏这些条件。

其中的一些策略和措施包括:破坏互斥条件、破坏不可抢占条件、破坏请求与保持条件、破坏循环等待条件以及合理地设置超时时间。通过综合运用这些策略和措施,我们可以有效地避免死锁的发生,从而保障系统的稳定性和可靠性。

你可能感兴趣的:(操作系统,java,jvm,开发语言)