前言:
通常我们都会遇到分页拉取的需求,比如与第三方系统同步数据,定时拉取全量数据做缓存,下面我们简单介绍下多线程分页写法
需求:
全量同步第三方系统数据,并在全部数据同步完后,统一做缓存数据处理
前置条件:
1.使用springBoot的ThreadPoolTaskExecutor 多线程封装数据
2.springBoot2.x、jdk8
完成步骤:
1.计算对应页数,把每页需求
2.循环多线程拉取
3.多线程内的子线程都完成了之后,再统一做缓存
具体代码:
1.多线程+CountDownLatch
java
public void doRepetition() {
log.info("处理重复组合编码 start");
doneService.initRingCode();
List<DoneRingPO> doneRingList = doneRingMapper.queryRepetitionRing();
if (CollectionUtils.isEmpty(doneRingList)) {
log.info("处理重复组合编码为空,处理重复组合编码 end");
return;
}
for (DoneRingPO item : doneRingList) {
List<DoneRingPO> repetitionCodeList = doneRingMapper.queryDoneRingByCode(Collections.singletonList(String.valueOf(item.getCode())));
for (int i = 1; i < repetitionCodeList.size(); i++) {
repetitionCodeList.get(i).setCode(redisTemplate.opsForValue().increment(DoneCacheKey.DONE_RING_CODE_INCR.getKey()));
}
for (DoneRingPO ringPo : repetitionCodeList) {
doneRingMapper.updateRingCode(ringPo);
}
}
log.info("处理重复组合编码 end");
}
2.多线程+CompletableFuture
java
public void testMulti(Integer totalNum) throws Exception {
int totalPage = totalNum;
final List<CompletableFuture<String>> futureList = new ArrayList<>();
for (int i = 1; i <= totalPage; i++) {
try {
final int page =i;
futureList.add(CompletableFuture.supplyAsync(() -> {
//TODO 执行耗时任务
log.info("耗时任务page={}",page);
return Integer.toString(page);
}, taskExecutor));
} catch (Exception e) {
log.error("线程异常....", e);
}
}
final CompletableFuture<Void> allOf = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[0]));
//线程等待完成
allOf.get();
//TODO 执行缓存任务
log.info("结束");
}