jstack分析死锁
写一个死锁:
先写两个锁,LockA, LockB。 在LockA 的opt 方法中调用LockB 方法,在LockB 的opt 方法中调用LockA 的opt 方法
/**
* A锁
*/
public class LockA {
Lock lock = new ReentrantLock();
public void opt(LockB b){
//A 锁
lock.lock();
try{
TimeUnit.SECONDS.sleep(20);
//B 锁
b.opt(this);
}catch (Exception e){
}finally {
lock.unlock();
}
}
}
/**
* B 锁
*/
public class LockB {
Lock lock = new ReentrantLock();
public void opt(LockA a){
//B 锁
lock.lock();
try{
TimeUnit.SECONDS.sleep(10);
//A锁
a.opt(this);
}catch (Exception e){
}finally {
lock.unlock();
}
}
}
//测试代码:
public static void main(String[] args) {
//构造LockA lockB
LockA a = new LockA();
LockB b = new LockB();
//线程2,先获取LockA的锁,再获取LockB的锁
Thread t1 = new Thread(){
@Override
public void run() {
a.opt(b);
}
};
//设置线程名
t1.setName("thread t1");
t1.start();
//线程2,先获取LockB的锁,再获取LockA的锁
Thread t2 = new Thread(){
@Override
public void run() {
b.opt(a);
}
};
//设置线程名
t2.setName("thread t2");
t2.start();
}
使用jps 找到pid
$ jps
15592 DeadLockTest
jstack 监控线程运行情况,使用-l参数打印出锁的情况
$ jstack -l 15592
日志如下:
2018-06-11 16:51:18
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode):
#日志生成时间,及虚拟机信息
"DestroyJavaVM" #14 prio&