背景:
批量数据采集接口,随着时间的推移,设备一次性上传的数据包越来越大,大到一次性需要处理64条数据,而每条数据需要花费大量的时间去处理,那么如果串行对任务进行处理的话,那么总时间就是N * 64
神操作来了:
使用FutureTask来进行并发操作
1、需要先定义一个并发处理线程池
1)注意注意,需要注意核心线程参数设置,否则会暴雷
- 注意注意,需要注意队列和最大线程数设置,否则会暴雷
// 定义一个任务列表,方便后面阻塞获取线程执行的结果
List<FutureTask<SaveCollectDataReq>> taskList = new ArrayList<>();
for (SaveCollectDataReq saveCollectDataReq : saveCollectDatas) {
FutureTask<SaveCollectDataReq> futureTask = new FutureTask(new BatchProduceTask(saveCollectDataReq, processOrderProduceService));
taskList.add(futureTask);
// 这里是将任务快速提交到线程池,并发处理
taskAsyncExecutor.submit(futureTask);
}
for (FutureTask<SaveCollectDataReq> saveCollectDataReqFutureTask : taskList) {
SaveCollectDataReq saveCollectDataReq = null;
try {
// 这里是获取并发处理的结果,方便后续的操作
saveCollectDataReq = saveCollectDataReqFutureTask.get();
if (Objects.isNull(saveCollectDataReq)) {
continue;
}
} catch (InterruptedException | ExecutionException e) {
log.error("数据批处理过程异常:",e);
throw new AiipcBizException(e.getMessage());
}
}
上面的代码上没什么坑,主要的坑在于线程池,线程的核心数、最大数、队列数以及拒绝策略,这几个参数都会影响接口的执行效率,了解一下
CallerRunsPolicy拒绝策略,这个策略是干什么的呢,他不会像其他策略那样抛弃任务或直接报异常,他会退化成由调用者执行这个任务,坑爹的地方自己想吧。