一、简介
从实现类的版本情况能看出,CompletableFuture是FutureTask的升级版。
CompletableFuture相比较于Callable+FutureTask组合、相比较于Future接口定义的基础功能确实做了诸多改进:
- 支持异步回调
- 手动完成任务并返回兜底值
- 支持进一步的非阻塞调用
- 支持链式调用
- 支持多任务合并
- 支持异常处理
二、具体用法
1、创建无返回值任务
// Demo 01:创建三个没有返回值的线程
// 1、创建自定义线程池
// [1]线程池的核心线程数
int corePoolSize = 3;
// [2]线程池的最大线程数
int maximumPoolSize = 5;
// [3]设置最大过期时间的数量
long keepAliveTime = 10;
// [4]设置最大过期时间的单位
TimeUnit timeUnit = TimeUnit.SECONDS;
// [5]存放等待中任务的阻塞队列
ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10);
// [6]创建线程工厂
ThreadFactory threadFactory = Executors.defaultThreadFactory();
// [7]创建拒绝策略对象
ThreadPoolExecutor.AbortPolicy abortPolicy = new ThreadPoolExecutor.AbortPolicy();
ThreadPoolExecutor threadPoolExecutor =
new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
timeUnit,
queue,
threadFactory,
abortPolicy);
// 2、使用 CompletableFuture 开辟新线程执行任务
CompletableFuture.runAsync(()->{
while (true) {
try {
TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + " is working");
}
}, threadPoolExecutor);
CompletableFuture.runAsync(()->{
while (true) {
try {
TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + " is working");
}
}, threadPoolExecutor);
CompletableFuture.runAsync(()->{
while (true) {
try {
TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + " is working");
}
}, threadPoolExecutor);
2、创建有返回值任务
// 1、获取线程池对象
ThreadPoolExecutor threadPool = ThreadPoolProvider.getThreadPool();
// 2、创建 “任务带有返回值” 的线程
CompletableFuture<String> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + " is working");
return "task 01 result";
}, threadPool);
CompletableFuture<String> future02 = CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread().getName() + " is working");
return "task 02 result";
}, threadPool);
CompletableFuture<String> future03 = CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread().getName() + " is working");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "task 03 result";
}, threadPool);
// 3、获取各个任务的执行结果
// get()方法会阻塞 main 线程(当前线程),一直到执行线程内任务的方法返回
String task01Result = future01.get();
System.out.println("task01Result = " + task01Result);
String task02Result = future02.get();
System.out.println("task02Result = " + task02Result);
String task03Result = future03.get();
System.out.println("task03Result = " + task03Result);
3、接收前面任务结果
// 测试目标:任务 1 处理完成之后,再处理任务 2,而且把任务 1 的结果传递给任务 2
// 1、获取线程池对象
ThreadPoolExecutor threadPool = ThreadPoolProvider.getThreadPool();
// 2、封装线程任务:链式执行
String finalTaskResult = CompletableFuture
.supplyAsync(() -> "prev task result", threadPool)
.thenApply((String prevTaskResult) -> { // 这里 Function 接口 apply() 方法入参是前面任务的返回值
// 打印前面任务传入的结果
System.out.println("prevTaskResult = " + prevTaskResult);
// 返回当前任务的结果
return prevTaskResult + "~~~~~~~~~~~";
}).get();
System.out.println("finalTaskResult = " + finalTaskResult);