业务场景:业务中有遇到接口响应较慢,数据库经过索引优化后,每次执行还需要1秒左右的需求,并且使用in操作特别慢,可以考虑用多线程去数据库读取数据,读取之后在代码中将结果封装好并返回前端。多线程的方式可以使用java8新特性CompletableFuture。
List<String> stuIds = stuService.getStuIds();
//将集合分成n等份
List<List<String>> lists = xxUtil.averageAssign(departmentIds, n);
final List<CompletableFuture<Map<String, Integer>>> futures = lists.parallelStream().map(subIds-> CompletableFuture.supplyAsync(() -> {
Map<String, Integer> map = new HashMap<>();
try {
for (String id: subIds) {
//根据id去查询数据库
Integer count = xxDao.getData(id);
map.put(id, count);
}
} catch (Exception e) {
log.error("执行sql失败", e.getMessage(), e);
}
return map;
//asyncTaskExecutor是自定义的线程池,这里也可以不传这个参数,默认使用jdk线程池
}, asyncTaskExecutor)).collect(Collectors.toList());
CompletableFuture<Void> completableFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
CompletableFuture<List<Map<String, Integer>>> listCompletableFuture = completableFuture.thenApply(v ->
futures.stream().map(future -> {
try {
return future.get();
} catch (Exception e) {
log.error("线程执行发生异常{}", e);
}
return new HashMap<>();
}).collect(Collectors.toList()));
try {
//从线程中获取结果,拿到结果后,自行处理
//get方法会等到所有的线程执行完毕,才会返回结果;换句话说,多线程的执行效率取决于最慢的那条线程的执行时间
List<Map<String,Integer>> listMap = listCompletableFuture.get();
} catch (Exception e) {
log.error("从线程中获取执行结果失败", e);
}