在IntelliJ IDEA中多线程并发代码的调试方法

一般来讲,多线程的并发及条件断点的debug是很难完成的,或许本篇文章会给你提供一个友好的调试方法。让你在多线程开发过程当中的调试更加的有的放矢。vue

咱们将经过一个例子来学习。在这里,我编写了一个多线程程序来计算此数学问题:100! + 100000!。即:100的阶乘 + 100000的阶乘。java

数学很差的同窗看这里,100 阶乘就是:1 2 3 …… 100 = ? ,简写为100!
import java.math.BigInteger;

public class MathProblemSolver {

    //开启两个线程
    public static void main(String arg[]){
        //第一个线程计算 100!
        FactorialCalculatingThread thread1 = new FactorialCalculatingThread(100);
        //第二个线程计算 100000!
        FactorialCalculatingThread thread2 = new FactorialCalculatingThread(100000);

        thread1.setName("Thread 1");
        thread2.setName("Thread 2");

        thread1.start();
        thread2.start();

        try {
            thread1.join(); //线程Jion,以使主线程在“线程1”和“线程2”都返回结果以前不会进一步执行
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        BigInteger result = thread1.getResult().add(thread2.getResult());
        System.out.println("将两个线程的计算结果相加等于:" + result);
    }

    //用于阶乘计算的线程类
    private static class FactorialCalculatingThread extends Thread {
        private BigInteger result = BigInteger.ONE;
        private long num;

        public FactorialCalculatingThread(long num) {
            this.num = num;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " 开始阶乘的计算:" + num);
            factorialCalc(num);
            System.out.println(Thread.currentThread().getName() + "执行完成");
        }

        //数的阶乘计算方法
        public void factorialCalc(long num) {
            BigInteger f = new BigInteger("1");
            for (int i = 2; i <= num; i++)
                f = f.multiply(BigInteger.valueOf(i));
            result = f;
        }

        public BigInteger getResult() { return result; }
    }
}

上面的代码解释spring

  • 开启两个线程,“Thread 1”计算(100!)和“Thread 2”计算(100000!)
  • 在main()方法中启动两个线程,而后调用thread1.join()thread2.join(),以使主线程在“线程1”和“线程2”都返回结果以前不会进一步执行。
  • 最后将两个线程的计算结果相加,获得100! + 100000!

下面就让咱们使用IntelliJ IDEA工具来调试这段多线程的代码。后端

Frames 与 Thread 面板

调试工具窗口的“Frames”面板包含一个下拉菜单。它的关注点在:因为断点而致使暂停的线程,并显示这些线程的调用堆栈信息。在下图中,断点位于main()方法中如图所示的位置,Frame向咱们显示了主线程的调用堆栈。springboot

若是要检查其余线程的调用堆栈,则能够从下拉列表中进行选择。多线程

Thread面板显示当前处于活动状态的全部线程。参考上面的代码,我在thread1.join()添加了一个断点。当应用程序在该断点处暂停时,咱们应该在此窗格中至少看到三个线程-“main”,“Thread 1”和“Thread 2”(请看下面的屏幕截图)。您能够双击每一个线程以观察其调用堆栈。并发

条件断点-只挂起符合条件的线程

假设我正在解决该程序中的错误,而且我只须要在“Thread 2”开始运行时就暂停执行。这代表我须要在FactorialCalculatingThread的run()方法的第一行上添加一个断点。由于咱们开启的两个线程使用的是同一段代码,因此咱们会遇到一个问题-使用该段代码的全部线程遇到断点都将被挂起,包括应用程序的“Thread 1”和“Thread 2”。我不但愿两个线程都暂停。该怎么作?前后端分离

咱们可使用条件断点功能。添加断点后,右键单击它,选中“suspend”并选择“Thread”。而后咱们添加条件currentThread().getName().equals("Thread 2"),以下面的屏幕快照所示。此条件确保调试器仅在当前线程的名称为“Thread 2”时才暂停当前线程:ide

如今执行调试程序,当应用暂停时,仅“Thread 2”被暂停。您能够经过如下步骤确认“Thread 1”已执行而且没有被挂起:微服务

1.在控制台中,您能够经过日志来验证“Thread 1”已运行并退出。

2.在“Thread”面板中,能够看到此时已经没有“Thread 1”,已经运行完成了!

在不一样的IDE版本中,配置条件断点的方式可能有所不一样。可是关键思想是要意识到这些功能的存在并加以使用。

欢迎关注个人博客,里面有不少精品合集

  • 本文转载注明出处(必须带链接,不能只转文字):字母哥博客

以为对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创做动力! 。另外,笔者最近一段时间输出了以下的精品内容,期待您的关注。

相关文章
相关标签/搜索