Java中的死锁检查

死锁检查:jstack、arthas

死锁检查

死锁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 >> threaddumps.log

注意⚠️:

  • 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.