代码逻辑如下:
public void fun() { List<Integer> list = new ArrayList<>(); for(int i = 1; i <= 12345; i++) { list.add(i); } int total = list.size(); int batchSize = total / 3; List<List<Integer>> partition = Lists.partition(list, batchSize); for (List<Integer> itemList : partition) { executorService.execute(() -> subFun(itemList)); } } private void subFun(List<Integer> list) { String threadName = Thread.currentThread().getName(); log.info("子线程{}开始执行。。。", threadName); for (Integer i : list) { ..... } log.info("子线程{}执行总数:{}", threadName, list.size()); }
总结就是将数据分为 3 块,并行执行,最终的日志结果是,子线程有 3 个开始执行了,却只有 2 个执行完,日志里没有异常信息,方法里也没有 return 的逻辑,有大佬给点排查思路吗
1 cJ8SxGOWRH0LSelC 2024-09-03 10:48:06 +08:00 你是跑的单元测试吗? 是不是因为主线程在子线程完成之前结束了, 导致进程停了。 可以在主线程尾部加个 sleep |
![]() | 2 3country OP @StinkyTofus 拿单元测试做了个例子,实际是晚上跑的定时任务 |
3 cJ8SxGOWRH0LSelC 2024-09-03 10:53:25 +08:00 除了我上面说的可能性, 就是你 executorService 的队列设置的太小了, 超过的任务被丢弃了。 正常的情况下子线程肯定会被执行, 没有抛出异常的情况下,不会自己挂掉。 |
![]() | 4 3country OP @StinkyTofus log.info("子线程{}开始执行。。。", threadName)这一行代码每一个子线程都执行了,我感到疑惑的是为什么有一个线程没有执行完方法,也没有异常信息 |
5 cJ8SxGOWRH0LSelC 2024-09-03 10:58:19 +08:00 @3country #4 不是都说了么,你跑的单元测试不能验证你提出的问题, 主线程提前结束了, 加个 sleep 就行了。 |
![]() | 6 cmai 2024-09-03 11:01:36 +08:00 怎么确定的没有异常信息?我看你方法里也没有 try catch |
![]() | 7 sagaxu 2024-09-03 11:09:47 +08:00 子线程不会自己挂掉。 executorService 可以是 daemon 也可以是非 daemon ,当他为 daemon 时,main 线程退出时,JVM 进程会结束,executorService 可能执行不完。 1. 确定 main 里面等待 executorService 执行完 2. 任务里面用 try-catch 包住,记录异常 |
8 MozzieW 2024-09-03 11:21:52 +08:00 1. 直接点,多加日志,try catch ,看能不能找到问题 2. 喝口水,上个厕所,回来代码多看几次 |
9 lujianwen9 2024-09-03 11:40:54 +08:00 executorService 没加异常处理吧 |
![]() | 10 AlanBrian 2024-09-03 11:50:14 +08:00 没有异常处理不会输出到日志文件的 |
![]() | 11 ArthurTsang 2024-09-03 11:52:25 +08:00 子线程 catch 下异常吧 |
12 fengpan567 2024-09-03 11:55:03 +08:00 为啥不先看看 error 日志 |
![]() | 13 magicZ 2024-09-03 13:22:24 +08:00 我也这么干过跑数据,比这个还粗暴直接 new 了 30 个线程跑,跑完生成文件。然后第二天我发现有几个文件没生成,也没有异常日志,检查几遍后发现就是 try catch 没指定的异常不对(代码自动生成的 IOException, 实际是 NPE 报错),导致线程挂了也没报错。 |
![]() | 14 magicZ 2024-09-03 13:27:14 +08:00 @magicZ 用了线程池有返回值异常在 future.get()时触发,无返回值,你的 AsyncUncaughtExceptionHandler 有没有拦截异常 |
![]() | 15 diagnostics 2024-09-03 14:05:57 +08:00 OOM 这类异常,可能就挂掉了,你只 Catch Exception 是不够的,我见过我同事,LogBack 不记录 fatal error 日志,排查半天才知道线程挂了 |