Java多线程 定位死锁--ThreadMXBean

定位死锁–ThreadMXBean

使用ThreadMXBean 可以检测程序中出现死锁的线程, 获取该线程的相关信息. 做一些对应的操作.

相比较于jstack 在命令中查看. 此种写代码的方式, 能够在线程出现死锁的时候, 做一些对应的操作.

示例代码如下 :

package com.thread.deadlock;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

/**
 * 类名称:ThreadMXBeanDetection
 * 类描述:  ThreadMXBean 检测死锁 
 *
 * @author: https://javaweixin6.blog.csdn.net/
 * 创建时间:2020/9/11 19:59
 * Version 1.0
 */
public class ThreadMXBeanDetection implements Runnable{
    
    
    //标记位, 不同的线程根据标记位执行不同的代码
    int flag = 1 ;

    //两把锁
    static Object o1 = new Object();
    static Object o2 = new Object();

    public static void main(String[] args) throws InterruptedException {
    
    
        ThreadMXBeanDetection r1 = new ThreadMXBeanDetection();
        ThreadMXBeanDetection r2 = new ThreadMXBeanDetection();
        //给不同的线程, 设置不同的标记位
        r1.flag=1;
        r2.flag=2;

        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);
        t1.start();
        t2.start();

        //让两个子线程执行
        Thread.sleep(1000);

        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();

        //获取发生死锁的线程id数组
        long[] deadlockedThreads = threadMXBean.findDeadlockedThreads();

        //判断发生死锁的线程是否为空
        if (deadlockedThreads != null && deadlockedThreads.length > 0) {
    
    

            for (int i = 0; i < deadlockedThreads.length; i++) {
    
    
                //传入发生死锁的线程id , 获取发生死锁的线程信息
                ThreadInfo threadInfo = threadMXBean.getThreadInfo(deadlockedThreads[i]);

                //打印出发生死锁线程的名称
                System.out.println("死锁的线程名称:  "+threadInfo.getThreadName());
            }
        }

    }

    @Override
    public void run() {
    
    
        //打印出标记位
        System.out.println("flag = "+flag);
        if (flag == 1) {
    
    
            synchronized (o1) {
    
    
                try {
    
    
                    //线程1持有锁o1, 并且等待500ms ,让线程2执行
                    Thread.sleep(500);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                //线程1尝试去获取锁o2
                synchronized (o2) {
    
    
                    System.out.println("线程1成功拿到两把锁");
                }

            }
        }

        if (flag == 2) {
    
    

            synchronized (o2) {
    
    

                try {
    
    
                    //持有锁o2, 并且等待500ms ,让线程1执行
                    Thread.sleep(500);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }

                //线程2尝试去获取锁o1
                synchronized (o1) {
    
    
                    System.out.println("线程2成功拿到两把锁");
                }
            }
        }
    }

}

主要的代码如下 , 在获取所有的发生死锁的线程, 对其遍历, 获取死锁线程的习惯信息.

可以获得如下的死锁线程信息, 此例子为打印出线程名称.

运行程序 打印如下 ,可以看到成功的打印了死锁线程名称.

猜你喜欢

转载自blog.csdn.net/qq_33229669/article/details/108540882