Java多线程 定位死锁--ThreadMXBean

Myth丶恋晨 2022-12-06 01:30 300阅读 0赞

文章目录

      • 定位死锁—ThreadMXBean

定位死锁–ThreadMXBean

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

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

示例代码如下 :

  1. package com.thread.deadlock;
  2. import java.lang.management.ManagementFactory;
  3. import java.lang.management.ThreadInfo;
  4. import java.lang.management.ThreadMXBean;
  5. /** * 类名称:ThreadMXBeanDetection * 类描述: ThreadMXBean 检测死锁 * * @author: https://javaweixin6.blog.csdn.net/ * 创建时间:2020/9/11 19:59 * Version 1.0 */
  6. public class ThreadMXBeanDetection implements Runnable{
  7. //标记位, 不同的线程根据标记位执行不同的代码
  8. int flag = 1 ;
  9. //两把锁
  10. static Object o1 = new Object();
  11. static Object o2 = new Object();
  12. public static void main(String[] args) throws InterruptedException {
  13. ThreadMXBeanDetection r1 = new ThreadMXBeanDetection();
  14. ThreadMXBeanDetection r2 = new ThreadMXBeanDetection();
  15. //给不同的线程, 设置不同的标记位
  16. r1.flag=1;
  17. r2.flag=2;
  18. Thread t1 = new Thread(r1);
  19. Thread t2 = new Thread(r2);
  20. t1.start();
  21. t2.start();
  22. //让两个子线程执行
  23. Thread.sleep(1000);
  24. ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
  25. //获取发生死锁的线程id数组
  26. long[] deadlockedThreads = threadMXBean.findDeadlockedThreads();
  27. //判断发生死锁的线程是否为空
  28. if (deadlockedThreads != null && deadlockedThreads.length > 0) {
  29. for (int i = 0; i < deadlockedThreads.length; i++) {
  30. //传入发生死锁的线程id , 获取发生死锁的线程信息
  31. ThreadInfo threadInfo = threadMXBean.getThreadInfo(deadlockedThreads[i]);
  32. //打印出发生死锁线程的名称
  33. System.out.println("死锁的线程名称: "+threadInfo.getThreadName());
  34. }
  35. }
  36. }
  37. @Override
  38. public void run() {
  39. //打印出标记位
  40. System.out.println("flag = "+flag);
  41. if (flag == 1) {
  42. synchronized (o1) {
  43. try {
  44. //线程1持有锁o1, 并且等待500ms ,让线程2执行
  45. Thread.sleep(500);
  46. } catch (InterruptedException e) {
  47. e.printStackTrace();
  48. }
  49. //线程1尝试去获取锁o2
  50. synchronized (o2) {
  51. System.out.println("线程1成功拿到两把锁");
  52. }
  53. }
  54. }
  55. if (flag == 2) {
  56. synchronized (o2) {
  57. try {
  58. //持有锁o2, 并且等待500ms ,让线程1执行
  59. Thread.sleep(500);
  60. } catch (InterruptedException e) {
  61. e.printStackTrace();
  62. }
  63. //线程2尝试去获取锁o1
  64. synchronized (o1) {
  65. System.out.println("线程2成功拿到两把锁");
  66. }
  67. }
  68. }
  69. }
  70. }

主要的代码如下 , 在获取所有的发生死锁的线程, 对其遍历, 获取死锁线程的习惯信息.
watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMjI5NjY5_size_16_color_FFFFFF_t_70_pic_center
可以获得如下的死锁线程信息, 此例子为打印出线程名称.
watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMjI5NjY5_size_16_color_FFFFFF_t_70_pic_center 1
运行程序 打印如下 ,可以看到成功的打印了死锁线程名称.
watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMjI5NjY5_size_16_color_FFFFFF_t_70_pic_center 2

发表评论

表情:
评论列表 (有 0 条评论,300人围观)

还没有评论,来说两句吧...

相关阅读

    相关 线

    / 死锁:二个线程同时锁住一个变量时。 锁住一个变量之后,尽快操作完成解锁,解锁之前不要再锁住其它变量,否则会互锁(死锁)。 /

    相关 线

    峨眉山月半轮秋,影入平羌江水流 Java线程的死锁一直都是经典的多线程问题;因为不同的线程都在等待根本不可能被释放的锁,从而导致所有的任务都不能继续执行; 示例代码:

    相关 线实例与定位

    既然可以上锁,那么假如有2个线程,一个线程想先锁对象1,再锁对象2,恰好另外有一个线程先锁对象2,再锁对象1。在这个过程中,当线程1把对象1锁好以后,就想去锁对象2,但是不巧,

    相关 线

    同步锁使用的弊端:当线程任务中出现了多个同步(多个锁)时,如果同步中嵌套了其他的同步。这时容易引发一种现象:程序出现无限等待,这种现象我们称为死锁。这种情况能避免就避免掉。