通过编程发现Java死锁

简介: 通过stack也可以发现死锁。测试类import java.util.concurrent.TimeUnit;public class Test { public static void main(String[] args) { DeadlockDetector ...

通过stack也可以发现死锁。

测试类

import java.util.concurrent.TimeUnit;

public class Test {
    public static void main(String[] args) {
        DeadlockDetector deadlockDetector = new DeadlockDetector(new DeadlockConsoleHandler(), 5, TimeUnit.SECONDS);
        deadlockDetector.start();

        final Object lock1 = new Object();
        final Object lock2 = new Object();
        Thread thread1 = new Thread(()->{
            synchronized (lock1) {
                System.out.println("Thread1 acquired lock1");
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                } catch (InterruptedException ignore) {
                }
                synchronized (lock2) {
                    System.out.println("Thread1 acquired lock2");
                }
            }
        });
        thread1.start();
        Thread thread2 = new Thread(()->{
            synchronized (lock2) {
                System.out.println("Thread2 acquired lock2");
                synchronized (lock1) {
                    System.out.println("Thread2 acquired lock1");
                }
            }
        });
        thread2.start();
    }
}

处理类

public class DeadlockConsoleHandler implements DeadlockHandler {
    @Override
    public void handleDeadlock(final ThreadInfo[] deadlockedThreads) {
        if (deadlockedThreads != null) {
            System.err.println("Deadlock detected!");
            Map<Thread, StackTraceElement[]> stackTraceMap = Thread.getAllStackTraces();
            for (ThreadInfo threadInfo : deadlockedThreads) {
                if (threadInfo != null) {
                    for (Thread thread : Thread.getAllStackTraces().keySet()) {
                        if (thread.getId() == threadInfo.getThreadId()) {
                            System.err.println(threadInfo.toString().trim());
                            for (StackTraceElement ste : thread.getStackTrace()) {
                                System.err.println("t" + ste.toString().trim());
                            }
                        }
                    }
                }
            }
        }
    }
}
import java.lang.management.ThreadInfo;
public interface DeadlockHandler {
    void handleDeadlock(final ThreadInfo[] deadlockedThreads);
}

关键类

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class DeadlockDetector {

    private final DeadlockHandler deadlockHandler;
    private final long period;
    private final TimeUnit unit;
    private final ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    final Runnable deadlockCheck = new Runnable() {
        @Override
        public void run() {
            long[] deadlockedThreadIds = mbean.findDeadlockedThreads();
            if (deadlockedThreadIds != null) {
                ThreadInfo[] threadInfos = mbean.getThreadInfo(deadlockedThreadIds);
                deadlockHandler.handleDeadlock(threadInfos);
            }
        }
    };

    public DeadlockDetector(final DeadlockHandler deadlockHandler, final long period, final TimeUnit unit) {
        this.deadlockHandler = deadlockHandler;
        this.period = period;
        this.unit = unit;
    }

    public void start() {
        this.scheduler.scheduleAtFixedRate(this.deadlockCheck, this.period, this.period, this.unit);
    }
}

测试结果

Thread1 acquired lock1
Thread2 acquired lock2
Deadlock detected!
"Thread-1" Id=12 BLOCKED on java.lang.Object@6a80bb83 owned by "Thread-0" Id=11
ttest.Test.lambda$main$1(Test.java:32)
ttest.Test$$Lambda$2/363771819.run(Unknown Source)
tjava.lang.Thread.run(Thread.java:745)
"Thread-0" Id=11 BLOCKED on java.lang.Object@6ebf220b owned by "Thread-1" Id=12
ttest.Test.lambda$main$0(Test.java:23)
ttest.Test$$Lambda$1/668386784.run(Unknown Source)
tjava.lang.Thread.run(Thread.java:745)
Deadlock detected!

 

目录
相关文章
|
1天前
|
Java API 调度
[Java并发基础]多进程编程
[Java并发基础]多进程编程
|
1天前
|
Java API 调度
[AIGC] 深入理解Java并发编程:从入门到进阶
[AIGC] 深入理解Java并发编程:从入门到进阶
|
1天前
|
前端开发 Java 测试技术
Java从入门到精通:4.1.1参与实际项目,锻炼编程与问题解决能力
Java从入门到精通:4.1.1参与实际项目,锻炼编程与问题解决能力
|
1天前
|
SQL Java 数据库连接
Java从入门到精通:2.3.2数据库编程——了解SQL语言,编写基本查询语句
Java从入门到精通:2.3.2数据库编程——了解SQL语言,编写基本查询语句
|
1天前
|
SQL Java 数据库连接
Java从入门到精通:2.3.1数据库编程——学习JDBC技术,掌握Java与数据库的交互
ava从入门到精通:2.3.1数据库编程——学习JDBC技术,掌握Java与数据库的交互
|
1天前
|
IDE Java 开发工具
Java从入门到精通:1.3.1实践编程巩固基础知识
Java从入门到精通:1.3.1实践编程巩固基础知识
|
5天前
|
IDE Java 物联网
《Java 简易速速上手小册》第1章:Java 编程基础(2024 最新版)
《Java 简易速速上手小册》第1章:Java 编程基础(2024 最新版)
13 0
|
3月前
|
Oracle Java 关系型数据库
Java 编程指南:入门,语法与学习方法
Java 是一种流行的编程语言,诞生于 1995 年。由 Oracle 公司拥有,运行在超过 30 亿台设备上。Java 可以用于: 移动应用程序(尤其是 Android 应用) 桌面应用程序 网络应用程序 网络服务器和应用程序服务器 游戏 数据库连接 等等!
37 1
|
8月前
|
存储 算法 Java
吐血整理Java编程基础入门技术教程,免费送
吐血整理Java编程基础入门技术教程,免费送
33 0
|
开发框架 Java C语言
Java学习路线-1:编程入门
Java学习路线-1:编程入门
71 0