首页 > 其他分享 >【多线程】定位线程死锁

【多线程】定位线程死锁

时间:2023-02-21 21:23:04浏览次数:40  
标签:lang java thread Object DeadLockDemo 死锁 线程 多线程 ThreadPoolExecutor

定位线程死锁的方式

  • 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

相关文章

  • Java多线程技能-线程的启动
    java多线程技能技术点:线程的启动如何使线程暂停如何使线程停止线程的优先级线程安全相关的问题进程和线程的定义及多线程的优点进程:进程是受操作系统管理的基本......
  • 多个线程操作一个对象
    packagecom.Java;//多个线程操作同一个对象//抢火车票例子//发现问题多个线程抢夺同个资源的情况下线程不安全数据紊乱publicclassTestThread4implementsRunnable......
  • Redis IO多线程的简要测试结果
    RedisIO多线程的简要测试结果摘要最近想简单确认一下IO多线程的对吞吐量的提升情况.正好手头有鲲鹏的机器,所以想直接进行一下验证顺便用一下4216进行一下对比.......
  • 继承Thread开启多线程下载图片(不推荐,java的单一继承性)
    packagecom.Java;importorg.apache.commons.io.FileUtils;importjava.io.File;importjava.io.IOException;importjava.net.URL;//练习多线程Thread,实现多线程下载图片......
  • 【多线程】高并发之——SimpleDateFormat类的线程安全问题和解决方案
    关于SimpleDateFormat熟悉Java的同学知道这个类是线程不安全的,但究竟是怎样不安全法,什么原因产生的线程不安全?估计未必全部人都能够答得上来(我也不能,emmmm)呃,想更好地......
  • Python的多进程和多线程
    前言:为什么有人说Python的多线程是鸡肋,不是真正意义上的多线程? 看到这里,也许你会疑惑。这很正常,所以让我们带着问题来阅读本文章吧。问题:1.什么是python......
  • 线程
    所有进程共享3~4G的内核空间,所以基于内核之间的通信能够实现。线程之间的通信:  1.不同进程的线程之间要进行通信,那就是进程之间的通信。  2.同一进程的线程间的通......
  • Android中使用线程池
    ArchTaskExecutor是androidx封装的线程接口接口内部是调用Executors开启4个线程的java线程池Executors.newFixedThreadPool(4,newThreadFactory(){切换到子线程......
  • 开源异步并行框架,完成任意的多线程编排、阻塞、等待、串并行结合、强弱依赖
    netty是一个经典的网络框架,提供了基于NIO、AIO的方式来完成少量线程支持海量用户请求连接的模型。netty里面充斥了大量的非阻塞回调模式,主要是靠Future/Promise异步模型来实......
  • springboot 使用@Async注解实现异步多线程
    1、在启动类中添加注解@SpringBootApplication@EnableAsync//@ImportResource(locations={"classpath:spring/my.xml"})publicclassDemoApplication{publi......