定位线程死锁的方式
- jstack pid
- 使用arthas
写一个死锁的小例子
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class DeadLockDemo {
static Object o1 = new Object();
static Object o2 = new Object();
static ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 120, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100));
static CountDownLatch countDownLatch = new CountDownLatch(2);
public static void main(String[] args) throws InterruptedException {
executor.execute(() -> {
synchronized (o1) {
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (o2) {
System.out.println("线程1获得了两把锁");
}
countDownLatch.countDown();
}
});
executor.execute(() -> {
synchronized (o2) {
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (o1) {
System.out.println("线程2获得了两把锁");
}
countDownLatch.countDown();
}
});
countDownLatch.await();
}
}
这个demo 启动后,线程就会死锁掉,
那怎样去查看是哪里发生了死锁呢?
方法一 jstack (推荐)
直接 jps 看一下要定位的进程的 Pid
然后 jstack pid > deadlock.log 打栈信息输出到一个文本中(当然,不输出也是可以的,个人喜欢)
然后在栈的后面,可以看到这么一段信息:
Java stack information for the threads listed above:
===================================================
"pool-1-thread-2":
at com.carrot.thread.deadlock.DeadLockDemo.lambda$main$1(DeadLockDemo.java:50)
- waiting to lock <0x000000076ac30978> (a java.lang.Object)
- locked <0x000000076ac30988> (a java.lang.Object)
at com.carrot.thread.deadlock.DeadLockDemo$$Lambda$2/1595428806.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"pool-1-thread-1":
at com.carrot.thread.deadlock.DeadLockDemo.lambda$main$0(DeadLockDemo.java:36)
- waiting to lock <0x000000076ac30988> (a java.lang.Object)
- locked <0x000000076ac30978> (a java.lang.Object)
at com.carrot.thread.deadlock.DeadLockDemo$$Lambda$1/1329552164.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.
这里就很清楚地看到是哪些线程发生了死锁了。。。(当然这个是造的例子,定位起来也比较简单,具体情况以真实案例为准吧)
嗯...
方法二 使用arthas
这个就没什么好说的了, 进入 arthas 后
使用 thread -b
不过这个信息偏少,虽然也够了
[arthas@761]$ thread -b
"pool-1-thread-2" Id=12 BLOCKED on java.lang.Object@1c01e8b4 owned by "pool-1-thread-1" Id=11
at com.carrot.thread.deadlock.DeadLockDemo.lambda$main$1(DeadLockDemo.java:53)
- blocked on java.lang.Object@1c01e8b4
- locked java.lang.Object@7bf02312 <---- but blocks 1 other threads!
at com.carrot.thread.deadlock.DeadLockDemo$$Lambda$2/1595428806.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Number of locked synchronizers = 1
- java.util.concurrent.ThreadPoolExecutor$Worker@3feba861
嗯,后续再补充吧。
标签:lang,java,thread,Object,DeadLockDemo,死锁,线程,多线程,ThreadPoolExecutor From: https://www.cnblogs.com/aaacarrot/p/17142502.html