java多线程实战二:CompletableFuture异步任务实现
CompletableFuture异步任务通过supplyAsync函数,支持返回数据。
主线程中pageCompletableFuture.get()非阻塞主线程,等待异步任务返回数据。
supplyAsync() 以Supplier函数式接口类型为参数,返回结果类型为U;Supplier接口的 get()是有返回值的,调用时会阻塞主线程。这里为了简单,直接顺序执行,没有join并行返回结果。
CompletableFuture默认线程池是ForkJoinPool.commonPool(),但为了实现线程之间互不影响,且便于定位问题,强烈推荐自定义线程池。
核心代码
public StudentPageVO listByParams(StudentVO studentVO, Query query) {
QueryWrapper<Student> queryWrapper = listQuryWrapperByParams(studentVO);
QueryWrapper<Student> sumQueryWrapper = listQuryWrapperByParams(studentVO);
//将RequestAttributes对象设置为子线程共享
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
RequestContextHolder.setRequestAttributes(servletRequestAttributes, true);
long startTime = System.currentTimeMillis();
//异步任务一
CompletableFuture<IPage<Student>> pageCompletableFuture = CompletableFuture.supplyAsync (() -> {
//任务1
return this.page(Condition.getPage(query), queryWrapper);
});
//异步任务二
CompletableFuture<Map<String, Object>> amountCompletableFuture = CompletableFuture.supplyAsync (() -> {
sumQueryWrapper.select(" sum(amount) as listSum ");
//查询总额
return this.getMap(sumQueryWrapper);
});
//阻塞主线程等待结果
IPage<StudentVO> pagesVO = StudentWrapper.build().pageVO(pageCompletableFuture.get());
//列表求和
Double listSum = 0.00;
if (amountCompletableFuture.get() != null) {
listSum = Double.valueOf(String.valueOf(amountCompletableFuture.get().get("listSum")));
}
//模拟主程序耗时时间
System.out.println("查询总共用时" + (System.currentTimeMillis() - startTime) + "ms");
StudentPageVO studentPageVO = new StudentPageVO();
BeanUtil.copy(pagesVO, studentPageVO);
studentPageVO.setListSum(listSum);
return studentPageVO;
}
本文介绍了如何使用Java的CompletableFuture实现异步任务,特别是通过supplyAsync函数创建非阻塞的任务。尽管默认使用ForkJoinPool.commonPool(),但建议为了线程独立和问题定位,采用自定义线程池。 Supplier接口在 CompletableFutures中用于提供有返回值的任务。
2361

被折叠的 条评论
为什么被折叠?



