需求描述
- 提供给前端一个接口,在接口中的逻辑是,为前端传递过来的git仓库增加分支
- 需求已经完成,但是接口处理速度过慢。因为每个git仓库增加分支都要远程调用gitlab的接口,但如果git仓库数量超过50个,那个整个耗时就会大于1分钟,超过前端超时控制,导致页面显示异常
需求分析
- 需要引入多线程,并发执行多个增加分支的操作
- 然后在主线程中等待多个任务执行完成,再继续后续如落库等操作
- 可以使用AbstractExecutorService.invokeAll 或者Completablefuture.allOf
具体实现
/**
* 新建分支
* @param branchName 分支名称
* @param gitOperaList 仓库列表
*/
public void createNewBranch(String branchName, List<GitOpera> gitOperaList) {
if (StringUtils.isBlank(branchName)) {
throw new RuntimeException("分支名称必输");
}
if (CollectionUtils.isEmpty(gitOperaList)) {
throw new RuntimeException("提交信息必选");
}
// 把仓库列表封装转换为任务列表
// gitForkJoinPool 为定义定义好的工作窃取线程池
List<CompletableFuture<Void>> completableFutures = gitOperaList.stream()
.map(gitOpera -> CompletableFuture.runAsync(() -> {
if (StringUtils.isBlank(gitOpera.getCommitId())) {
gitOpera.setBranchName("【失败】commitId为空");
} else {
try {
GitlabUtils.createBranch(branchName, gitOpera.getCommitId(), gitOpera.getGitUrl());
gitOpera.setBranchName("【成功】" + branchName);
} catch (Exception e) {
log.error(e.getMessage());
gitOpera.setBranchName("【失败】新建分支失败:" + e.getMessage());
}
}
gitOpera.setId(null);
}, gitForkJoinPool))
.collect(Collectors.toList());
try {
// 批量执行任务,并阻塞所有等待任务执行完成
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[completableFutures.size()])).get();
} catch (Exception e) {
throw new RuntimeException("多线程执行异常,请重新执行" + e.getMessage());
}
// 后续落库等操作
updateOrSaveListByUnion(gitOperaList);
}
实现效果
使用多线程后,可以达到100个仓库,20秒内增加分支操作完成,前端不再超时异常