死锁检查
死锁demo代码:
import static java.lang.System.out;
/**
* 死锁demo
* Created by RuzzZZ on 2017/2/8.
*/
public class Deadlock implements Runnable {
private Deadlock other;
public void setOther(Deadlock other) {
this.other = other;
}
private synchronized void checkOtherLock(Deadlock other) throws InterruptedException {
out.println("CheckOtherLock start.Current thread name is :" + Thread.currentThread().getName());
//线程先休息一下,保证两个线程都进入同步方法中
Thread.sleep(100L);
//doSomething()是同步方法,所以它会尝试去获取other对象的锁
//当两个线程互相争夺锁时,理论上是会互相阻塞的,所以都无法执行doSomething()方法
other.doSomething();
out.println("CheckOtherLock over.Current thread name is :" + Thread.currentThread().getName());
}
private synchronized void doSomething() {
out.println("THis is doSomething() method!");
}
@Override
public void run() {
try {
this.checkOtherLock(other);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Deadlock deadlock1 = new Deadlock();
Deadlock deadlock2 = new Deadlock();
deadlock1.setOther(deadlock2);
deadlock2.setOther(deadlock1);
out.println("start");
new Thread(deadlock1).start();
new Thread(deadlock2).start();
}
}
jstack
Oracle官方关于jstack的使用指南:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstack.html#BABGJDIF
输出JVM的thread dump : jstack -l
注意⚠️:
- jstack的线程存在用户概念,可能需要sudo(或者启动用户)。
- dump线程jvm会有停顿,线上环境慎用
arthas
thread -b, 找出当前阻塞其他线程的线程
$ thread -b
"Thread-1" Id=11 BLOCKED on com.xzy.concurrent.Deadlock@23a5521 owned by "Thread-0" Id=10
at com.xzy.concurrent.Deadlock.doSomething(Deadlock.java:28)
- blocked on com.xzy.concurrent.Deadlock@23a5521
at com.xzy.concurrent.Deadlock.checkOtherLock(Deadlock.java:23)
- locked com.xzy.concurrent.Deadlock@72a50942 <---- but blocks 1 other threads!
at com.xzy.concurrent.Deadlock.run(Deadlock.java:34)
at java.lang.Thread.run(Thread.java:748)
Affect(row-cnt:0) cost in 8 ms.