CompletableFuture+@Async("asyncTaskExecutor")

114 阅读1分钟

“携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情

CompletableFuture

JDK1.8才新加入的一个实现类,实现了Future, CompletionStage2个接口。

实现CompletionStage接口是为了实现流式编程。

CompletableFuture 自带多任务组合方法allOf和anyOf allOf是等待所有任务完成,构造后CompletableFuture完成。 anyOf是只要有一个任务完成,构造后CompletableFuture完成。

全流失处理转换成CompletableFuture[]+allOf组装成一个无返回值CompletableFuture,join等待执行完毕。返回结果whenComplete获取。

创建CompletableFuture集合

List<CompletableFuture<Integer>> tasks = new ArrayList<>();
CompletableFuture.allOf(tasks.toArray(new CompletableFuture[0])).join();

CompletableFuture满足并发执行,顺序完成可按任务执行完成顺序获取的目标。 而且支持每个任务的异常返回,配合流式编程,用起来速度飞起。JDK源生支持,API丰富,推荐使用。

FutrueFutureTaskCompletionServiceCompletableFuture
原理Futrue接口第三列文本居左第二列文本居右第三列文本居左
多任务并发执行支持支持支持支持
获取任务结果的顺序支持任务完成先后顺序未知支持任务完成的先后顺序支持任务完成的先后顺序
异常捕获自己捕捉自己捕捉自己捕捉源生API支持,返回每个任务的异常
建议CPU高速轮询,耗资源,可以使用,但不推荐功能不对口,并发任务这一块多套一层,不推荐使用。推荐使用,没有JDK8CompletableFuture之前最好的方案,没有质疑API极端丰富,配合流式编程,速度飞起,推荐使用!

@Async("asyncTaskExecutor")

基本使用

这个注解的作用在于可以让被标注的方法异步执行,但是有几个前提条件

1. 配置类上添加`@EnableAsync`
2. 需要与不执行的方法的所在类由Spring管理
3. 需要异步执行的方法上添加了`@Async`注解

在实际使用场景中,可以先定义线程池,在方法上添加注解。 定义线程池

/**
 * 线程池的配置
 */
@Configuration
public class AsyncPoolConfig {

    private static final int MAX_POOL_SIZE = 50;

    private static final int CORE_POOL_SIZE = 20;

    @Bean("asyncExecutor")
    public AsyncTaskExecutor asyncTaskExecutor() {
        ThreadPoolTaskExecutor asyncTaskExecutor = new ThreadPoolTaskExecutor();
        //线程池维护线程的最大数量
        asyncTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
        //线程池维护现成的最小数量
        asyncTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
        asyncTaskExecutor.setThreadNamePrefix("async-thread-pool-");
        asyncTaskExecutor.initialize();
        return asyncTaskExecutor;
    }
}

线程执行任务:在方法上@Async("asyncExecutor")

@Asyc+CompletableFuture

  1. 添加@Async注解
  2. 返回值声明为:CompletableFuture
  3. 配置@Component或@Service等,使组件可以被扫描到
@Async("asyncExecutor")
public CompletableFuture<Integer> queryVarList() throws InterruptedException {
    try {
        //具体实现逻辑 
        ......
        //为任务设置返回值
        return CompletableFuture.completedFuture(1);
    } catch (Exception e) {
        logger.error("失败信息{}",e);
    }
    return CompletableFuture.completedFuture(-1);
}