文章目录
应用背景
数据刷新接口:全量/增量数据拉取,数据量2w条,拉取数据逻辑是通过表A、B去组合表C的一条记录中的数据,进行新增/更新,由于拉取数据后还需要进行数据版本记录的创建,全量数据刷新时,需要等待10分钟余,通过 多线程+分批处理 的思路将接口响应时长优化到3分钟左右
多线程+分批次 方法代码示例
// 定义动态线程池
private static final int THREAD_POOL_SIZE = Math.max(2, Runtime.getRuntime().availableProcessors() * 2);
@Override
public ServiceResponse updateTnMdBudgetOrganization(Date date, List<String> organizationCodeList) {
// 创建一个固定大小的线程池来并发处理任务
ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
// 创建一个集合来存储处理每个批次的 Future 对象
List<Future<Void>> futures = new ArrayList<>();
int batchSize = 1000;
// 根据 batchSize 将列表分页, 将每一页(或批次)提交给线程池执行
for (int i = 0; i < distinctList.size(); i += batchSize) {
int start = i;
int end = Math.min(i + batchSize, distinctList.size());
List<String> batchList = distinctList.subList(start, end);
// 定义一个 Callable 任务来处理每个批次
Callable<Void> task = () -> {
processBatch(batchList);
return null;
};
// 将任务提交给线程池并获取 Future 对象
futures.add(executorService.submit(task));
}
// 等待所有任务完成
for (Future<Void> future : futures) {
try {
// 调用 Future 的 get() 方法来等待任务完成
future.get();
} catch (Exception e) {
// 记录错误信息
Log.error(LogBuilder.builder().type(LogType.NORMAL).tag("MDM").error("存在批次执行异常:{}" + e).build());
// 打印异常堆栈跟踪
e.printStackTrace();
}
}
// 关闭线程池
executorService.shutdown();
// 返回成功响应
return ServiceResponse.success();
}