通常来说,多线程的并发及条件断点的 debug 是很难实现的,或者本篇文章会给你提供一个敌对的调试办法。让你在多线程开发过程中的调试更加的对症下药。
咱们将通过一个例子来学习。在这里,我编写了一个多线程程序来计算此数学问题:100! + 100000!
。即:100 的阶乘 + 100000 的阶乘。
数学不好的同学看这里,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;}
}
}
下面的代码解释
- 开启两个线程,“Thread 1”计算(100!)和“Thread 2”计算(100000!)
- 在 main()办法中启动两个线程,而后调用
thread1.join()
和thread2.join()
,以使主线程在“线程 1”和“线程 2”都返回后果之前不会进一步执行。 - 最初将两个线程的计算结果相加,失去
100! + 100000!
上面就让咱们应用 IntelliJ IDEA 工具来调试这段多线程的代码。
Frames 与 Thread 面板
调试工具窗口的“Frames”面板 蕴含一个下拉菜单。它的关注点在:因为断点而导致暂停的线程,并显示这些线程的调用堆栈信息。在下图中,断点位于 main()办法中如图所示的地位,Frame 向咱们显示了主线程的调用堆栈。
如果要查看其余线程的调用堆栈,则能够从下拉列表中进行抉择。
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”时才暂停以后线程:
当初执行调试程序,当利用暂停时,仅“Thread 2”被暂停。您能够通过以下步骤确认“Thread 1”已执行并且没有被挂起:
1. 在控制台中,您能够通过日志来验证“Thread 1”已运行并退出。
2. 在“Thread”面板中,能够看到此时曾经没有“Thread 1”,曾经运行实现了!
在不同的 IDE 版本中,配置条件断点的形式可能有所不同。然而要害思维是要意识到这些性能的存在并加以应用。
欢送关注我的博客,外面有很多精品合集
- 本文转载注明出处(必须带连贯,不能只转文字):字母哥博客。
感觉对您有帮忙的话,帮我点赞、分享!您的反对是我不竭的创作能源!。另外,笔者最近一段时间输入了如下的精品内容,期待您的关注。
- 《手摸手教你学 Spring Boot2.0》
- 《Spring Security-JWT-OAuth2 一本通》
- 《实战前后端拆散 RBAC 权限管理系统》
- 《实战 SpringCloud 微服务从青铜到王者》
- 《VUE 深入浅出系列》