模拟死锁以及使用jstack命令分析查找死锁原因
程序员文章站
2024-03-18 10:03:52
...
模拟死锁以及使用jstack命令分析查找死锁原因
先定义两个类Lock1、Lock2
public class Lock1 {
private final Object lock = new Object();
private Lock2 lock2;
public void method1(){
synchronized (lock){
System.out.println("Lock1->method1==========");
lock2.method1();
}
}
public void method2(){
synchronized (lock){
System.out.println("Lock1->method2==========");
}
}
public Lock1(Lock2 lock2) {
this.lock2 = lock2;
}
}
public class Lock2 {
private final static Object lock = new Object();
private Lock1 lock1;
public void method1() {
synchronized (lock){
System.out.println("Lock2->method1==========");
}
}
public void method2() {
synchronized (lock){
lock1.method1();
System.out.println("Lock2->method2==========");
}
}
public void setLock1(Lock1 lock1) {
this.lock1 = lock1;
}
}
再写一个测试类
public class DeadLockTest {
public static void main(String[] args) {
Lock2 lock2 = new Lock2();
Lock1 lock1 = new Lock1(lock2);
lock2.setLock1(lock1);
new Thread(){
@Override
public void run() {
while (true) {
lock1.method1();
}
}
}.start();
new Thread(){
@Override
public void run() {
while (true) {
lock2.method2();
}
}
}.start();
}
}
执行测试类会发现,程序在打印完Lock1->method1==========之后就卡主不动了,观察CPU和内存占用也是很稳定的状态,这时候就应该考虑是不是程序死锁了
使用jvm自带的命令jstack来帮助我们分析查找死锁原因
首先打开本地的命令窗口,键入jps命令,找到我们正在运行的程序,如图
编号25520的程序正是我们在跑的demo,然后再使用jstack命令打印出堆栈信息(jstack 25520),截取部分信息,如图
通过上图(Found 1 deadlock)我们可以明显的看出来,当前程序发生了死锁
这部分堆栈信息则直接告诉了我们,Thread-1当前持有的锁和希望获取的锁,Thread-0当前持有的锁和希望获取的锁,通过观察发现,这两个线程所持有的锁正是对方想要的锁
通过这部分堆栈信息还可以看出到底是哪一行代码造成的死锁,这时候我们就可以有针对性的去解决这个死锁问题了
锁和希望获取的锁,通过观察发现,这两个线程所持有的锁正是对方想要的锁**
通过这部分堆栈信息还可以看出到底是哪一行代码造成的死锁,这时候我们就可以有针对性的去解决这个死锁问题了