“携手创作,共同成长!这是我参与「掘金日新计划 · 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丰富,推荐使用。
Futrue | FutureTask | CompletionService | CompletableFuture | |
---|---|---|---|---|
原理 | 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
- 添加@Async注解
- 返回值声明为:CompletableFuture
- 配置@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);
}