Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >在IntelliJ IDEA中多线程并发代码的调试方法

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

作者头像
字母哥博客
发布于 2020-09-23 07:18:27
发布于 2020-09-23 07:18:27
3.4K02
代码可运行
举报
运行总次数:2
代码可运行

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

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

数学不好的同学看这里,100 阶乘就是:1 2 3 …… 100 = ? ,简写为100!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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版本中,配置条件断点的方式可能有所不同。但是关键思想是要意识到这些功能的存在并加以使用。

喜欢 (1)or分享 (0)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Junit单元测试不支持多线程测试问题全解析
今天@段段提出了一个很好的问题,她发现单元测试时如果开多个线程,主线程运行结束就结束了,并不会等待子线程结束。
明明如月学长
2021/08/31
1.3K0
Junit单元测试不支持多线程测试问题全解析
Java 线程学习
Java 线程相关 如何创建线程(两种方式,区别,使用场景) 线程状态调度 多线程数据共享(会有什么问题,如何实现共享,多线程操作同一个变量会有什么问题,如果不希望有问题怎么做) 数据传递 线程池相关(如何创建线程池,要注意什么(初始化线程内部变量),几种常用的使用方式) 1. 线程创建 通常创建线程有两种方式,一个是继承 Thread, 一个是实现 Runnable; 下面则分别实现以做演示,然后说一下这两种的区别,应该如何选择 创建线程 创建线程和使用的一个小case如下, 注意的是线程启动是调用st
一灰灰blog
2018/02/06
6910
Java 线程学习
多线程的创建方式以及及Thread类详解
前两种方式都存在一个问题:重写的run方法均不能直接返回结果,不适合需要返回线程执行结果的场景。而通过实现Callable接口则可以做到这一点。
用户11369558
2024/11/20
2970
多线程的创建方式以及及Thread类详解
C++多线程-多线程调试
软件调试是我们软件开发过程中的重要一课。在前面,我们也讨论过程序调试,比如说这里。今天,我们还可以就软件调试多讲一些内容。比如说条件断点,数据断点,多线程断点等等。
cwl_java
2020/01/15
3.9K0
11.多线程、多进程和线程池编程
RLock:在同一个线程里面,可以连续多次调用acquire,一定要注意acquire和release的次数相等
zhang_derek
2019/08/26
4200
11.多线程、多进程和线程池编程
Java 多线程编程(上)
https://blog.csdn.net/weixin_44510615/article/details/102617286
润森
2019/11/04
4620
多线程与多进程 | 多线程
是计算机中已运行程序的实体。进程与程序不同,程序本身只是指令、数据及其组织形式的描述,进程才是程序的真正运行的实体。
数据STUDIO
2021/06/24
9940
Java多线程与并发
进程是资源分配的基本单位,所有与进程有关的资源都记录在进程控制块PCB中,以表示进程拥有这些资源或者正在使用它们,进程也是抢占处理机的调度单位,它拥有完整的虚拟内存地址空间,当进程发生调度时,不同的进程拥有不同的地址空间,而同一进程内的不同线程共享同一地址空间。与进程相对应,线程与资源分配无关,它属于某一个进程,并与进程内的其它线程共享进程的资源。
ha_lydms
2023/08/10
2270
Java多线程与并发
【小家Java】Future、FutureTask、CompletionService、CompletableFuture解决多线程并发中归集问题的效率对比
开启线程执行任务,不管是使用Runnable(无返回值不支持上报异常)还是Callable(有返回值支持上报异常)接口,都可以轻松实现。那么如果是开启线程池并需要获取结果归集的情况下,如何实现,以及优劣?
YourBatman
2019/09/03
2.7K1
【小家Java】Future、FutureTask、CompletionService、CompletableFuture解决多线程并发中归集问题的效率对比
如何调试多线程程序
在上一篇文章《使用 gdb 调试多进程程序 —— 以调试 nginx 为例》我们介绍了如何使用 gdb 调试多进程程序,这篇文章我们来介绍下如何使用 gdb 调试多线程程序,同时这个方法也是我阅读和分析一个新的 C/C++ 项目常用的方法。
范蠡
2020/07/16
4.1K0
如何调试多线程程序
多线程(一):创建线程和线程的常用方法
进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。
全栈程序员站长
2022/08/11
1.1K0
多线程(一):创建线程和线程的常用方法
java中的多线程
  线程是进程中一个小的执行单位,线程是不能脱离进称独立存在的,一个进程中可以有一个或多个线程。
别团等shy哥发育
2023/02/25
2.1K0
java中的多线程
简简单单聊一下多线程的join()方法
不可否认的是,在这个圆滑当道的时代,如果一个人太过于正直,刚正不阿,那么可能会四处碰壁,而那些世故的机会主义往往如鱼得水,我们面对 这样一个社会规则,我觉得我们可以适当收起自己的锐利,做到知圆滑而不圆滑,知世故而不世故,应该保持一颗年轻的心态,而不是随着年龄的增长 而变得油腻,圆滑,世故。
小四的技术之旅
2022/07/26
4510
简简单单聊一下多线程的join()方法
c# 温故而知新: 线程篇(一) 下
Abort 方法: 其实 Abort 方法并没有像字面上的那么简单,释放并终止调用线程,其实当一个线程调用 Abort方法时,会在调用此方法的线程上引发一个异常: ThreadAbortException ,让我们一步步深入下对这个方法的理解: 1 首先我们尝试对主线程终止释放 static void Main(string[] args) { try { Thread.CurrentThread.Abort
逸鹏
2018/04/10
6700
c# 温故而知新: 线程篇(一) 下
【深入浅出C#】章节 9: C#高级主题:多线程编程和并发处理
多线程编程和并发处理的重要性和背景 在计算机科学领域,多线程编程和并发处理是一种关键技术,旨在充分利用现代计算机系统中的多核处理器和多任务能力。随着计算机硬件的发展,单一的中央处理单元(CPU)已经不再是主流,取而代之的是多核处理器,这使得同时执行多个任务成为可能。多线程编程允许开发人员将一个程序拆分成多个线程,这些线程可以并行执行,从而提高程序的性能和响应速度。 为什么多线程在现代应用中至关重要?
喵叔
2023/08/26
5K0
Java开发者必知:掌握线程生命周期的重要性
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
喵手
2024/05/10
1210
Java开发者必知:掌握线程生命周期的重要性
Java多线程
例如打开你的计算机上的任务管理器,会显示出当前机器的所有进程,QQ,Chrome等,当QQ运行时,就有很多子任务在同时运行。比如,当你边打字发送表情,边好友视频时这些不同的功能都可以同时运行,其中每一项任务都可以理解成“线程”在工作。
用户10358987
2024/04/23
1210
Java多线程
Python 多线程并发程序设计与分析
难点2:同一段代码,再不加锁的情况下,可能被多个线程同时执行,这会造成很多麻烦,比如变量的赋值不正确,方法的重复调用,而如果加锁,或者通过join阻塞方式等来控制,那么又如同运行单进程,效率低下,达不到,“并发”,“高速”的效果。
授客
2019/09/11
5110
Python 多线程并发程序设计与分析
Python多线程、阻塞线程、线程同步和守护线程实例详解
1、主线程是程序本身,看不到的,主线程和子线程没有依赖关系,同步执行的,若主线程先执行完,会等子线程执行完毕,程序结束
王大力测试进阶之路
2020/02/10
4.9K0
Java多线程二: Thread中几个比较重要的方法
sleep作为最常见的方法之一,其作用就是使调用sleep的所在线程进入睡眠状态。它会让调用该方法的所在线程主动放弃CPU资源,进入阻塞状态,如果指定了睡眠时间,到达了指定时间之后线程就会进入就绪状态,等待调度器的调用。sleep()方法是Thread类的静态方法,如果调用线程对象.sleep()方法并不是该线程就休眠,而是哪一个线程里面执行了sleep()方法哪一个线程就休眠。
全栈学习笔记
2022/04/24
2670
推荐阅读
相关推荐
Junit单元测试不支持多线程测试问题全解析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验