代码逻辑如下:
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
StinkyTofus 67 天前
你是跑的单元测试吗? 是不是因为主线程在子线程完成之前结束了, 导致进程停了。 可以在主线程尾部加个 sleep
|
2
3country OP @StinkyTofus 拿单元测试做了个例子,实际是晚上跑的定时任务
|
3
StinkyTofus 67 天前
除了我上面说的可能性, 就是你 executorService 的队列设置的太小了, 超过的任务被丢弃了。 正常的情况下子线程肯定会被执行, 没有抛出异常的情况下,不会自己挂掉。
|
4
3country OP @StinkyTofus log.info("子线程{}开始执行。。。", threadName)这一行代码每一个子线程都执行了,我感到疑惑的是为什么有一个线程没有执行完方法,也没有异常信息
|
5
StinkyTofus 67 天前
@3country #4 不是都说了么,你跑的单元测试不能验证你提出的问题, 主线程提前结束了, 加个 sleep 就行了。
|
6
cmai 67 天前
怎么确定的没有异常信息?我看你方法里也没有 try catch
|
7
sagaxu 67 天前
子线程不会自己挂掉。
executorService 可以是 daemon 也可以是非 daemon ,当他为 daemon 时,main 线程退出时,JVM 进程会结束,executorService 可能执行不完。 1. 确定 main 里面等待 executorService 执行完 2. 任务里面用 try-catch 包住,记录异常 |
8
MozzieW 67 天前
1. 直接点,多加日志,try catch ,看能不能找到问题
2. 喝口水,上个厕所,回来代码多看几次 |
9
lujianwen9 67 天前
executorService 没加异常处理吧
|
10
AlanBrian 67 天前
没有异常处理不会输出到日志文件的
|
11
ArthurTsang 67 天前
子线程 catch 下异常吧
|
12
fengpan567 67 天前
为啥不先看看 error 日志
|
13
magicZ 67 天前
我也这么干过跑数据,比这个还粗暴直接 new 了 30 个线程跑,跑完生成文件。然后第二天我发现有几个文件没生成,也没有异常日志,检查几遍后发现就是 try catch 没指定的异常不对(代码自动生成的 IOException, 实际是 NPE 报错),导致线程挂了也没报错。
|
15
diagnostics 67 天前
OOM 这类异常,可能就挂掉了,你只 Catch Exception 是不够的,我见过我同事,LogBack 不记录 fatal error 日志,排查半天才知道线程挂了
|