1. CompletableFuture概述
- Future接口实现了异步的功能,而CompletableFuture在此基础上进行了功能强化。
- CompletableFuture实现了Future和CompletionStage接口
![截屏2022-07-14 10.08.16](https://i-blog.csdnimg.cn/blog_migrate/f006bbc5066f206a59760b7146820170.png)
2. CompletionStage接口
- CompletionStage代表异步计算过程中的某一个阶段,一个阶段完成后可能会触发另外一个阶段
- 一个阶段的执行可能是被单个阶段的完成触发,也可能是由多个阶段一起触发.有些类似Linux系统的管道分隔符传参数
public class CompletableFutureTest2 {
public static void main(String[] args)throws Exception {
/**
1.当一个线程依赖另一个线程时,可以使用thenApply()方法来把这两个线程串行化(第二个任务依赖第一个任务的结果)
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
2.它可以处理正常的计算结果,或者异常情况
public CompletableFuture<T> whenComplete(BiConsumer<? super T,? super Throwable> action)
3.异常的处理操作
public CompletableFuture<T> exceptionally(Function<Throwable,? extends T> fn)
*/
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {e.printStackTrace();}
return 1;
}).thenApply(result -> {
return result+3;
// whenComplete虽然得到异常信息,但是无法修改返回数据
}).whenComplete((v,e)->{
if(e==null){
System.out.println(Thread.currentThread().getName()+"\t"+"result = " + v);
}
})
// exceptionally: 同时感知异常,同时返回默认值
.exceptionally(e->{
e.printStackTrace();
return null;
});
System.out.println(Thread.currentThread().getName()+"\t"+"over...");
//主线程不要立即结束,否则CompletableFuture默认使用的线程池会立即关闭,暂停几秒
try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {e.printStackTrace();}
}
}
3.CompletableFuture创建方式
CompletableFuture有一个空参构造器,但是不推荐使用
CompletableFuture 提供了四个静态方法来创建一个异步操作
- runAsync方法不支持返回值
- supplyAsync可以支持返回值,我们一般用supplyAsync来创建
//runAsync方法不支持返回值
public static CompletableFuture<Void> runAsync(Runnable runnable)
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
//supplyAsync可以支持返回值
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
@Test
public void testReturnVoid() throws ExecutionException, InterruptedException {
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"---- working");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
System.out.println(completableFuture.get());
}
没有指定Executor的方法会使用ForkJoinPool.commonPool()
作为它的线程池执行异步代码。如果指定线程池,则使用指定的线程池运行。以下所有的方法都类同
@Test
public void testReturnParam() throws Exception {
ExecutorService threadPool = Executors.newFixedThreadPool(3);
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(new Supplier<String>() {
@Override
public String get() {
System.out.println(Thread.currentThread().getName() + "---- working");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "hello SupplAsync";
}
},threadPool);
System.out.println(completableFuture.get());
}