Junit测试多线程无法得到结果的问题解决

 更新时间:2021年05月25日 09:08:00   作者:Mr_Right_  
在测试一个文件转换工具类的时候,发生一个有趣的现象,同样的输入,使用Main函数可以正确解析,得到结果,使用Junit却无法得到结果,神奇的是,即使捕获Throwable,也无法捕获到仍和异常。
class Main {
    public static void main(String[] args) {
        String trxFileDir = args[0];
        String targetDir = args[1];
        boolean isDecode = Boolean.parseBoolean(args[2]);
        ParseMojo parseMojo = new ParseMojo(trxFileDir,targetDir,isDecode);
        parseMojo.execute();
    }
}
    @Test
    public void executeEncode() {
        String trxFileDir = "E:\\MAE\\code\\MyMojoParse\\src\\main\\resources\\inputFile\\";
        String targetDir = "E:\\MAE\\code\\MyMojoParse\\src\\main\\resources\\outputFile\\";
        boolean isEncode = true;
        ParseMojo parser = new ParseMojo(trxFileDir, targetDir, isEncode);
        parser.execute();
    }

解析工具支持多线程,核心代码如下

		 Arrays.stream(trxFiles).forEach(trx -> PARSE_POOL.execute(() -> {
                    convertToBinaryFile(trx);
            }));

猜测可能原因

首先当前问题和业务逻辑无关,初步怀疑是多线程和UT的问题,可能Junit进行测试的时候,主线程结束会导致子线程也终止。

问题排查

添加打印,查看文件的中断处

打印结果如下:

很明显,主进程结束退出的时候,子进程还没有执行完成,且每次执行到的位置不一致

问题原因

分析Junit源码

    public static void main(String args[]) {
        TestRunner aTestRunner = new TestRunner();
        try {
            TestResult r = aTestRunner.start(args);
            if (!r.wasSuccessful()) {
                System.exit(FAILURE_EXIT);
            }
            System.exit(SUCCESS_EXIT);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(EXCEPTION_EXIT);
        }
    }

这是Junit运行的入口,我们可以发现,不管Junit测试是否成功,都会调用System.exit(),而这个方法会用来结束当前正在运行的java虚拟机。当status=0时表示正常结束,status=1表示异常退出(强制退出,程序未执行完也会退出)。JVM都关闭了,子线程还靠什么运行呢?所以这就是问题所在。

总结

在需要被测试类为多线程执行任务的时候,注意不要直接使用Junit单元测试,可能由于系统退出,导致任务异常中断。

注意要使并发工具类如 CountDownLatch、thread.join()保证任务中的线程全部执行完毕。

以上就是Junit测试多线程无法得到结果的问题解决的详细内容,更多关于Junit测试多线程无法得到结果的资料请关注脚本之家其它相关文章!

相关文章

  • 如何通过Java打印Word文档

    如何通过Java打印Word文档

    这篇文章主要介绍了如何通过Java打印Word文档,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Java项目常见工具类详解

    Java项目常见工具类详解

    这篇文章主要为大家总结了平时在Java项目中使用的工具类:JWT工具类、MD5工具类、视频点播工具类、公共常量工具类、日期操作工具类、Http客户端工具类和获取IP工具类。需要的可以参考一下
    2021-12-12
  • Spring源码分析容器启动流程

    Spring源码分析容器启动流程

    Spring的启动流程可以归纳为三个步骤:初始化Spring容器,注册内置的BeanPostProcessor的BeanDefinition到容器中、将配置类的BeanDefinition注册到容器中、调用refresh()方法刷新容器
    2022-09-09
  • RocketMQ producer容错机制源码解析

    RocketMQ producer容错机制源码解析

    这篇文章主要为大家介绍了RocketMQ producer容错机制源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Java设计模式之桥梁(Bridge)模式

    Java设计模式之桥梁(Bridge)模式

    这篇文章主要介绍了Java设计模式之桥梁(Bridge)模式,文中有非常详细的代码示例,对正在学习Java设计模式的小伙伴们有很好的帮助,需要的朋友可以参考下
    2021-05-05
  • java基础学习JVM中GC的算法

    java基础学习JVM中GC的算法

    这篇文章主要介绍了java基础学习JVM中GC的算法,通过图文加深对GC算法思路的理解。
    2017-11-11
  • Java遍历Map对象的四种方式

    Java遍历Map对象的四种方式

    本文给大家介绍java遍历map对象的四种方式,对java中遍历map感兴趣的朋友可以一起了解了解
    2015-10-10
  • 通过Java实现文件断点续传功能

    通过Java实现文件断点续传功能

    用户上传大文件,网络差点的需要历时数小时,万一线路中断,不具备断点续传的服务器就只能从头重传,而断点续传就是,允许用户从上传断线的地方继续传送,这样大大减少了用户的烦恼。本文将用Java语言实现断点续传,需要的可以参考一下
    2022-05-05
  • SpringBoot使用自动配置xxxAutoConfiguration

    SpringBoot使用自动配置xxxAutoConfiguration

    这篇文章介绍了SpringBoot自动配置xxxAutoConfiguration的使用方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12
  • Java使用JSONObject需要的6个jar包下载地址

    Java使用JSONObject需要的6个jar包下载地址

    这篇文章主要介绍了Java使用JSONObject需要的6个jar包下载地址,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11

最新评论