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

作者:Mr_Right_ 时间:2023-01-01 22:12:52 

目录
  • 猜测可能原因

  • 问题排查

  • 问题原因

  • 总结


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测试多线程无法得到结果的问题解决

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

问题原因

分析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()保证任务中的线程全部执行完毕。

来源:https://juejin.cn/post/6965778873476726815

标签:Junit,测试,多线程
0
投稿

猜你喜欢

  • 基于Spring Boot使用JpaRepository删除数据时的注意事项

    2023-04-03 09:05:39
  • Android实现从网络获取图片显示并保存到SD卡的方法

    2023-10-09 22:08:56
  • C#集合之字典的用法

    2022-04-11 23:27:19
  • java中断线程的正确姿势完整示例

    2023-01-27 06:33:58
  • C#创建、读取和修改Excel的方法

    2023-02-24 06:28:16
  • 微信跳一跳辅助Java代码实现

    2022-03-31 19:12:03
  • 使用Springboot自定义注解,支持SPEL表达式

    2023-11-20 01:18:58
  • IDEA 端口占用的解决方法(推荐)

    2023-09-05 06:05:15
  • SpringBoot整合screw实现数据库文档自动生成的示例代码

    2023-11-29 05:30:15
  • SpringBoot使用Druid数据源的配置方法

    2023-08-19 19:52:11
  • 使用jenkins部署springboot项目的方法步骤

    2022-06-05 05:18:31
  • Java CPU性能分析工具代码实例

    2023-09-28 04:52:54
  • 关于通过java调用datax,返回任务执行的方法

    2023-11-28 21:26:45
  • C#实现简单俄罗斯方块

    2023-06-18 07:18:36
  • C#中的时间显示格式(12小时制VS24小时制)

    2021-10-19 12:58:41
  • Andriod使用多线程实现轮播图片

    2023-07-27 15:47:31
  • 浅谈Maven的build生命周期和常用plugin

    2022-11-03 01:47:52
  • Unity3D游戏开发数据持久化PlayerPrefs的用法详解

    2022-11-11 23:16:00
  • Java应用EasyExcel工具类

    2023-07-07 18:45:32
  • Spring Cloud 的 Hystrix.功能及实践详解

    2023-11-19 06:40:46
  • asp之家 软件编程 m.aspxhome.com