死锁是指两个或两个以上的进程在执行过程中,死死抓住对方需要的资源然后还不撒手造成的一种堵塞的现象,如果没有人去插手可能还会阻塞其他线程的运行,最后导致系统崩溃
网络异常,图片无法展示
|
死锁的产生
死锁的产生需要 同时 满足以下四个条件:
- 互斥条件:某个资源在某段时间内只能被同一个线程占用
- 请求和保持条件:一个线程获取到某个资源后保持占有并等待下一个被其他线程所占有的资源
- 不可抢占条件:线程对已获得的资源在未使用完之前,不能被其他线程剥夺,抢占, 即资源只能在线程完成任务之后自动释放
- 循环等待条件:发生死锁时,必然存在两个或以上线程占有各自的资源同时等待对方释放资源,从而造成环路等待的情况
线程在产生死锁之后,只能通过外部干预来解决,比如重启,或者 kill线程等
死锁的预防
想要预防死锁就要打破死锁的四个条件,其中互斥条件是锁本身的特性无法被破坏,其他三个条件都可以破坏
对于请求和保持条件:我们可以在对锁的第一次执行的时候一次性的申请所有的资源
对于循环等待条件:我们可以对资源进行排序,使得所有锁都按照一定的顺序进行资源的请求
对于不可抢占条件:当占有部分资源的锁进一步的申请其他资源的时候,如果申请不到或者超时则放弃主动释放所占有的资源
死锁的检测
出现死锁以后,有以下两种方法去对死锁进行检测以及定位
1.可以通过 jstack命令去到处现成的 dump日志,然后从 dump日志中定位到具体思索的程序代码
2.通过 JDK自带的 JConsole可视化监视工具连接正在运行的本地或者远程的JVM,对运行在Java应用程序的线程进行远程连接并进行死锁检测功能