目录
死锁的产生
锁是个非常有用的工具,运用场景很多,因为使用起来既简单又易于理解。但是它也会带来一些困扰,那就是会引起死锁,一旦产生死锁,就会造成系统功能不可用。
先来看一段代码,线程A和线程B互相等待对方释放锁。
package com.example.demo.deadlock;
public class LockDemo {
private static final Object A = new Object();
private static final Object B = new Object();
public static void main(String[] args) {
new Thread(()->{
synchronized (A){
System.out.println("Tom获得锁");
try {
Thread.sleep(50L);
} catch (InterruptedException e) {
e.printstacktrace();
}
synchronized (B){
System.out.println("Tom抓到了Jerry");
}
}
}).start();
new Thread(()->{
synchronized (B){
System.out.println("Jerry获得锁");
synchronized (A){
System.out.println("Jerry甩掉了Tom");
}
}
}).start();
}
}
代码的执行结果为:
由此可以明显看出,程序没有结束,AB都在等对方释放资源,这就产生了死锁问题。
那么问题来了?
如何排查死锁?这里我只介绍3个,其余的就自行了解吧~因为我没了解
- jstack
- jconsole
- jvisualvm
死锁的排查工具
1.jstack
先来说jstack,在这之前,我们首先打开cmd输入jps,即可看到java的运行程序进程id。找到自己的程序,我的就是22064。然后输入jstack 22064,就可以看到一大段代码。
这里就可以清楚的看到,我们的线程是死锁状态。
那有的人就说了,你这啥啊一堆黑黢黢的,一点也不直观。
好的,直观的咱也整一个。
2.jconsole
废话不多说,直接cmd执行jconsole就会出现jconsole控制台,如下图所示。除了这个方法,也可以打开 JDK 的 bin 目录,找到 jconsole 并双击打开,因为jconsole是jdk自带的一套java虚拟机执行状况监视器,能够用来监控虚拟机的内存、线程、cpu使用情况等。这里就不说别的了,我是用cmd打开的。
点击连接进入,选择“不安全的连接”进入监控主页,即可看到如下图所示:
选择线程标签,在底部可以看到有“检测死锁”的按钮,点击后就会将死锁的进程显示出来。
3.jvisualvm
jvisualvm也是jdk自带的性能分析工具,在bin目录下,所以打开方式也是直接在bin目录中找到,双击打开即可。
jvisualvm可以监控本地,远程的java进程,实时查看进程的cpu、线程等参数,对java程序生成dump文件,并对dump文件进行分析。
双击左侧要调试的程序,在右边选择线程,即可看到检测出死锁的提示。
我们可以通过线程Dump来查看是哪个线程出现了问题,以下线程信息告诉我们是LockDemo类的第27行和第18行引起的死锁。
那么以上,就讲解了三种排查工具的使用,欢迎补充~
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。