1.为什么需要CompletabledFuture?
CompletabledFuture类是为了Java多线程而产生。
假设一个场景,你需要执行30个计算任务,各个任务之间相互独立,每个人任务耗时一分钟,你需要在尽快执行完这30个任务,并且对30个任务的结果进行统计汇总。
如果你有一个64核心的CPU,那么为了更加高效执行完所有任务,通常会选择写一个多线程程序,让30个任务并行执行。但是,并行执行的任务属于多个线程,一般情况下无法获取其返回值,那么如何对其结果进行汇总统计?
CompletabledFuture应运而生。
2.关于CompletabledFuture的历史
Java语言在JDK 1.5时首次提出了Future类用于获取异步任务的返回结果,但是功能并不完善。在JDK 1.8时,功能更加完善的CompletabledFuture类诞生了。
简单对比二者区别。
Future | CompletabledFuture |
需要阻塞线程进行等待 | 使用回调函数,无需阻塞线程 |
无法对多线程进行复杂流程控制 | 通过回调函数实现非常复杂的异步流程控制(多线程执行顺序) |
因为阻塞,性能略差 | 无需在阻塞等待浪费时间,性能更优 |
3.简单的CompletabledFuture最佳实践
代码结合Springboot框架,更多复杂写法后续更新...
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
/**
* 主线程
*
* @Author hyx
* @Date 2021/3/3
*/
@Service
public class Main {
@Autowired
AsyService asyService;
public void mainThread(){
List<CompletableFuture<String>> futureList = new ArrayList<CompletableFuture<String>>();
//把多个异步任务的结果状态放进一个list里
for(int i = 0; i < 10; i++){
CompletableFuture future = asyService.dealSomeAsyTask();
futureList.add(future);
}
//阻塞主线程,直到所有异步任务执行完毕
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()]));
try {
combinedFuture.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//获取各个线程结果
for(CompletableFuture future: futureList){
try {
String status = (String)future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
package com.example.demo;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.*;
/**
* 模拟一个异步执行的线程
*
* @Author hyx
* @Date 2021/3/3
*/
@Service
public class AsyService {
@Async
public CompletableFuture<String> dealSomeAsyTask() {
//计算...
String status = "success";
return CompletableFuture.completedFuture(status);
}
}