java线程死锁的检测方法

#java线程死锁的检测方法

Java中线程状态:新建(New)、可运行(Runnable)、等待(Wating)、超时等待(Timed_Wating)、阻塞(Blocked)、Terminated(终止)。所有状态在Thread.state枚举类中。

状态转换图:
当线程中互相等待对方释放锁的时候就会都变成Blocked状态形成死锁,产生死锁的必要条件: **1. 互斥条件:**一个资源每次只能被一个进程使用。 **2. 请求与保持条件:**一个进程因请求资源而阻塞时,对已获得的资源保持不放。 **3. 不剥夺条件:**进程已获得的资源,在末使用完之前,不能强行剥夺。 **4. 循环等待条件:**若干进程之间形成一种头尾相接的循环等待资源关系。

例如: 测试threadA和threadB都进入无线等待,形成死锁。 代码如下:

public class ThreadTest {
	private static final Object lockA = new Object();
	private static final Object lockB = new Object();

	public static void main(String[] args) throws Exception {
		Thread threadA = new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (lockA) {
					System.out.println("a thead run ...");
					try {
						Thread.sleep(3000);
					} catch (InterruptedException e) {
					}
					synchronized (lockB) {
						System.out.println("a thead end ...");
					}
				}
			}
		});
		threadA.setName("threadA");
		Thread threadB = new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (lockB) {
					System.out.println("b thead run ...");
					synchronized (lockA) {
						System.out.println("b thead end ...");
					}
				}
			}
		});
		threadB.setName("threadB");
		threadA.start();
		Thread.sleep(1000);
		threadB.start();
	}
}

当发生的死锁后,JDK自带了两个工具(jstack和JConsole),也可以使用VisualVm进行监控。

VisualVm

VisualVM会看到如下: 通过threadump可以看到更加详细的信息:

jstack

通过jstack展示线程堆栈信息(以Windows环境为例) 1.找到运行当前程序的JVM的进程id(测试使用的是eclipse运行,17572pid是eclipse) 2.执行jstack [pid] 这样就能清晰的查出是threadAthreadB线程互相等待产生死锁。推荐将线程命名,这样在线程堆栈dump中就能准确的定位是哪个线程,如果不进行命名将会由系统自动命名,不便于问题的查找。

工具是如何检测死锁的呢?

产生死锁也就意味着先生之间的等待关系出现了闭合环路,发生死锁。我们可以将等待关系想象成一个单项链表。那么也就将问题转化为判断这个链表中是否出现环路。如何检测单项链表中是否有闭合环路,请看我的另一片博客。

转载于:https://my.oschina.net/hongliangsun/blog/1546375

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值