异步计算场景
当我们编写的后台方法中有大量 互相之间不影响的计算等复杂任务的时候 如:指标计算等 我们可以考虑使用自定义线程池使用Java的异步方法实现 并行处理提高相应速度
自定义线程池
我们通过Jdk的new ThreadPoolExecutor可以实现对线程池参数的自定义:
ThreadPoolExecutor对象的几大参数:
1.核心线程数
2.最大线程数
3.空闲线程存活时间
4.时间单位
5.等待队列
6.拒绝策略
ThreadFactory itemCountThreadFactory = new ThreadFactoryBuilder().setNameFormat("count-thread-%d")
.setBackingThreadFactory(Executors.defaultThreadFactory()).get();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(6, 6, 0L,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), itemCountThreadFactory);
这里创建了一个六个线程的线程池 自定义了线程工厂ThreadFactory 可以自定义线程名称
异步方法
supplyAsyncWithTrace 用于创建一个可以获取返回值的任务 就是我们可以拿到这个方法的返回结果 并且可以进行追踪 就是整个任务的tractId不会变(这个不了解的可以不关注 使用supplyAsync方法)
thenApply方法是在supplyAsyncWithTrace 方法运行结束后 进行回调的方法 用户在supplyAsyncWithTrace 方法中的某个任务执行完毕之后进行回调操作
supplyAsyncWithTrace方法两个参数 一个是线程任务,一个是自定义的线程池 就是使用我们上面自定义的线程池来运行提交的任务
CompletableFutureHandler.supplyAsyncWithTrace(() -> {
//执行你的业务方法
Integer evaluationsCount = 5;
return evaluationsCount;
}, threadPoolExecutor).thenApply(evaluationsCount -> {
LOGGER.info("evaluationsCount:" + evaluationsCount);
return evaluationsCount;
});
完整代码
// 自定义线程工厂
ThreadFactory itemCountThreadFactory = new ThreadFactoryBuilder().setNameFormat("count-thread-%d")
.setBackingThreadFactory(Executors.defaultThreadFactory()).get();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(6, 6, 0L,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), itemCountThreadFactory);
CompletableFuture<Integer> evaluationsCountThenApply = CompletableFutureHandler.supplyAsyncWithTrace(() -> {
//执行你的业务方法
Integer evaluationsCount = 5;
return evaluationsCount;
}, threadPoolExecutor).thenApply(evaluationsCount -> {
LOGGER.info("evaluationsCount:" + evaluationsCount);
return evaluationsCount;
});
LOGGER.info("evaluationsCountThenApply" + evaluationsCountThenApply.get(Constants.NUM_10, TimeUnit.SECONDS));
evaluationsCountThenApply.get(Constants.NUM_10, TimeUnit.SECONDS)) 方法用于获取异步任务的最终结果 第一个参数是超时时间 第二个参数是单位 这里超过十秒没获取到就结束
注:LOGGER.info 为本人实现的日志打印 复制报错可考虑替换为自己的日志实现方式