其实这种导入优化有点老生常谈了,感觉核心就两个:
1:大数据分批处理(分治)
2:充分利用线程池来多线程处理,比如我遇到的解析 excle,然后校验词条,然后批量导入,这里每一步都可以用多线程。
通用的处理方式应该就这样吧
/**
* 导入黑名单词语列表,使用批处理和多线程方式
* @param words 要导入的词语列表
* @throws InterruptedException 如果等待过程被中断
*/
public void importBlacklistWords(List<String> words) throws InterruptedException {
int totalWords = words.size();
// 计算需要多少批次,向上取整确保所有词语都被处理
int batchCount = (int) Math.ceil((double) totalWords / BATCH_SIZE);
// 创建CountDownLatch用于同步所有批次的处理
CountDownLatch latch = new CountDownLatch(batchCount);
// 批量导入
for (int i = 0; i < batchCount; i++) {
// 计算每批的起始和结束索引
int start = i * BATCH_SIZE;
int end = Math.min(start + BATCH_SIZE, totalWords);
// 获取当前批次的词语子列表
List<String> batchWords = words.subList(start, end);
// 提交线程池处理每批数据
executorService.submit(() -> {
// 检查当前操作是否有效(可能是检查系统状态或权限)
if(valid()){
try {
// 导入当前批次的词语
importBatch(batchWords);
} catch (SQLException e) {
// 处理导入失败的情况
handleBatchFailure(batchWords);
} finally {
// 无论成功与否,都减少等待计数
latch.countDown();
}
}
});
}
// 等待所有批次处理完成,或者直到超时
latch.await(TIMEOUT, TimeUnit.SECONDS);
// 关闭线程池
executorService.shutdown();
}