java中如何检查线程死锁_Java线程死锁查看分析方法、工具,怎么检查死锁,死锁的缘由是什么?...

如何查看是否有Java线程死锁?下面介绍两种方法。html

一.Jconsole

Jconsole是JDK自带的图形化界面工具,使用JDK给咱们的的工具JConsole,能够经过打开cmd而后输入jconsole打开。java

da2e9a5a5b27f180b89a0daef22811f6.png

链接到须要查看的进程。ide

bf63f01d5886245120a02d8d1f081a0a.png

打开线程选项卡,而后点击左下角的“检测死锁” 。工具

c901365411e91d75af11fa988abf1f62.png

jconsole就会给咱们检测出该线程中形成死锁的线程,点击选中便可查看详情:post

c3502663e707a976ddeb0c9478133e5e.png

d777fe06a2046ff7b5bcd3bb0db95423.png

从上图中咱们能够看出: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命令)

4e469ec0e59b7834edd151988eb14bb9.png

2.看一下jstack的使用

b8c7eca4d5b27c41a265d6dcc4e8af66.png

3.jstack输出线程dump信息到文件

ef90891d84ea03de207938cff8960f45.png

用比较工程查看带-l和不带-l的区别以下:

3d4edfe3dae11fa330b8c7222abb97ff.png

4.查看dump文件,而后进行分析

3c610b52f6e749f790680cf0ff5dbbc8.png

其中有一行是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。

5e08a882afad826e0c0027f9dca800bd.png

从而定位到死锁发生的缘由,及具体位置:Thread-0得到了锁lock1,接下来指望得到锁lock2,(第20行),可是此时Thread-1得到了锁lock2,接下来指望得到锁lock2,(第37行),于是发生了死锁。

附实例DeadThread.java代码:

23d1e80c7a1c4eeeaa289a81.html

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();

}

}

23d1e80c7a1c4eeeaa289a81.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值