如何查看是否有Java线程死锁?下面介绍两种方法。html
一.Jconsole
Jconsole是JDK自带的图形化界面工具,使用JDK给咱们的的工具JConsole,能够经过打开cmd而后输入jconsole打开。java
链接到须要查看的进程。ide
打开线程选项卡,而后点击左下角的“检测死锁” 。工具
jconsole就会给咱们检测出该线程中形成死锁的线程,点击选中便可查看详情:post
从上图中咱们能够看出:this
在线程Thread-1中,从状态能够看出,它想申请java.lang.Object@35b4e829这个资源,可是这个资源已经被Thread-0拥有了,因此就堵塞了。url
在线程Thread-0中,从状态能够看出,它想申请java.lang.Object@2db8dc9这个资源,可是这个资源已经被Thread-1拥有了,因此就堵塞了。.net
Thread-1一直等待java.lang.Object@35b4e829资源,而Thread–0一直等待java.lang.Object@2db8dc9资源,因而这两个线程就这么僵持了下去,形成了死锁。命令行
二.Jstack线程
Jstack是JDK自带的命令行工具,主要用于线程Dump分析。
1.咱们先用Jps来查看java进程id(或者Linux的ps命令)
2.看一下jstack的使用
3.jstack输出线程dump信息到文件
用比较工程查看带-l和不带-l的区别以下:
4.查看dump文件,而后进行分析
其中有一行是at DeadThread.run(DeadThread.java:37),说明Thread-1实在DeadThread类的37行处发生死锁,其中at DeadThread.run(DeadThread.java:21),说明Thread-0是在DeadThread类的21行处发生死锁。详细的jstack dump文件分析请参看:http://www.cnblogs.com/flyingeagle/articles/6853454.html。
从而定位到死锁发生的缘由,及具体位置:Thread-0得到了锁lock1,接下来指望得到锁lock2,(第20行),可是此时Thread-1得到了锁lock2,接下来指望得到锁lock2,(第37行),于是发生了死锁。
附实例DeadThread.java代码:
public class DeadThread implements Runnable {
public String username;
public Object lock1 = new Object();
public Object lock2 = new Object();
@Override
public void run() {
// TODO Auto-generated method stub
if (username.equals("a")) {
synchronized (lock1) {
try {
System.out.println("username = " + username);
System.out.println(Thread.currentThread().getName());
Thread.sleep(3000);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
synchronized (lock2) {
System.out.println("按lock1->lock2的顺序执行代码");
}
}
}
if (username.equals("b")) {
synchronized (lock2) {
try {
System.out.println("username = " + username);
System.out.println(Thread.currentThread().getName());
Thread.sleep(3000);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
synchronized (lock1) {
System.out.println("按lock2->lock1顺序执行代码");
}
}
}
}
public void setFlag(String username) {
this.username = username;
}
public static void main(String[] args) {
DeadThread dt1 = new DeadThread();
dt1.setFlag("a");
Thread t1 = new Thread(dt1);
t1.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
dt1.setFlag("b");
Thread t2 = new Thread(dt1);
t2.start();
}
}