先说一下业务场景,在查询用户信息的时候需要顺便查询很多与用户相关的信息,这些信息都在不同的系统里面。每个信息都要查几个不同的表才能得到完整数据,相对比较耗时。
伪代码如下:
List<User> user = getUser();
// 循环
for(User u:user) {
u.setXXX(//某信息查询结果);
U.setXXX(//某信息查询结果);
}
解决方案也很简单,把顺序查询转为并发查询即可
ExecutorService executor = new ThreadPoolExecutor(
8, 100, 5,
TimeUnit.MINUTES,
new ArrayBlockingQueue<>(10000)
);
Random random=new Random(10);
//模拟查询用户列表
List<User> list=selectUsers();
// 任务列表
List<CompletableFuture<User>> fList = new ArrayList<>();
list.forEach(u->{
CompletableFuture<User> f = CompletableFuture.supplyAsync(
//执行耗时较长的业务代码,这里模拟一下
()->{
u.setAge(random.nextInt(100));
u.setName(UUID.randomUUID().toString());
return u;
},
executor
);
fList.add(f);
});
// 阻塞,等待所有任务执行完成
CompletableFuture<Void> all= CompletableFuture.allOf(fList.toArray(new CompletableFuture[0]));
//因为allOf没有返回值,所以需要通过thenApply回调函数获取结果
CompletableFuture<List<User>> allUser=all.thenApply(v-> fList.stream().map(a-> {
try {
return a.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return null;
}).collect(Collectors.toList()));
list=allUser.get();
这里使用allOf等待任务执行完毕,然后通过thenApply回调函数获取结果。再通过get拿到处理过后的用户集合。最后返回结果给前端。