文章目录
【笔记于学习尚硅谷课程所作】
3、 CompletableFuture 异步编排
3.1 创建异步对象
以下四个静态方法用来为一段异步执行的代码创建CompletableFuture
对象
//使用ForkJoinPool.commonPool()作为它的线程池执行异步代码
public static CompletableFuture<Void> runAsync(Runnable runnable)
//使用传入的线程池,但是它以Runnable函数式接口类型为参数,所以CompletableFuture的计算结果为空
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
//supplyAsync方法以Supplier<U>函数式接口类型为参数,CompletableFuture的计算结果类型为U
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
因为方法的参数类型都是函数式接口,所以可以使用lambda
表达式实现异步任务
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("-----处理业务逻辑-----");
return "处理结果";
}, executor);
3.2 获取值
public T get()
public T get(long timeout, TimeUnit unit)
public T getNow(T valueIfAbsent)
public T join()
示例
future.get();
3.3 计算结果完成时的处理
当CompletableFuture
的计算结果完成,或者抛出异常的时候,我们可以执行以下四个方法
//可以处理正常的计算结果,或者异常情况,并且使用与之前相同的线程执行
public CompletableFuture<T> whenComplete(BiConsumer<? super T,? super Throwable> action)
//方法不以Async结尾,意味着Action使用相同的线程执行,而Async可能会使用其它的线程去执行(如果使用相同的线程池,也可能会被同一个线程选中执行)
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action)
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor)
//处理异常,如果原始的CompletableFuture抛出异常,就会触发这个方法,并返回一个新的CompletableFuture
public CompletableFuture<T> exceptionally(Function<Throwable,? extends T> fn)
示例
CompletableFuture.supplyAsync(() -> {
System.out.println("hello");
return "result";
}).whenCompleteAsync((result, e) -> {
System.out.println(result + "-->whenCompleteAsync ");
}).exceptionally((e) -> {
System.out.println("exception---> " + e);
return "exception";
});
3.4 handle方法
和complete一样,可对结果做最后的处理(可以处理异常),可改变返回值
public <U> CompletableFuture<U> handle(BiFunction<? super T,Throwable,? extends U> fn)
public <U> CompletableFuture<U> handleAsync(BiFunction<? super T,Throwable,? extends U> fn)
public <U> CompletableFuture<U> handleAsync(BiFunction<? super T,Throwable,? extends U> fn, Executor executor)
示例
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("hello");
return "result";
});
CompletableFuture<Integer> future2 = future1.handle((r, e) -> {
System.out.println("future1-->handle");
return 1;
});
3.5线程串行化
//不接受上个任务的结果,不返回当前任务结果
public CompletableFuture<Void> thenRun(Runnable action)
public CompletableFuture<Void> thenRunAsync(Runnable action)
public CompletableFuture<Void> thenRunAsync(Runnable action, Executor executor)
//接收上个任务的结果,不返回当前任务结果
public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor)
//接收上个任务的结果,返回当前任务结果
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
示例
//thenRun方法
CompletableFuture.supplyAsync(() -> {
System.out.println("hello");
return "hello";
}).thenRun(() -> {
System.out.println("----");
});
//thenAccept方法
CompletableFuture.supplyAsync(() -> {
System.out.println("hello");
return "hello";
}).thenAccept(r -> {
System.out.println(r);
}).thenAccept(r -> {
System.out.println(r);
});
//thenApply方法
CompletableFuture.supplyAsync(() -> {
System.out.println("hello");
return "hello";
}).thenApply((r) -> {
System.out.println(r);
return r+"world";
}).thenApply((r) -> {
System.out.println(r);
return 1;
});
3.6 两任务组合–都完成
/*以下方法的触发条件:--->之前的两个任务都完成,开始执行本任务。A&&B==1-->执行C的关系*/
//runAfterBoth:不获取future结果,,没有返回值
public CompletionStage<Void> runAfterBoth(CompletionStage<?> other,Runnable action);
public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other,Runnable action);
public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other,Runnable action,Executor executor);
//thenAcceptBoth:获取两个future任务的结果,没有返回值
public <U> CompletionStage<Void> thenAcceptBoth(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action);
public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action);
public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action,Executor executor);
//thenCombine:获取两个future任务的结果,并且有返回值
public <U,V> CompletionStage<V> thenCombine(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletionStage<V> thenCombineAsync(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletionStage<V> thenCombineAsync(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn,Executor executor);
示例
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
return 100;
});
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
return -100;
});
/*-------------------------------------------------------------------------*/
//runAfterBoth方法
future1.runAfterBoth(future2, ()->{
System.out.println("-------");
});
//thenAcceptBoth方法
future1.thenAcceptBoth(future2,(x,y) ->{
System.out.println(x+y);
});
//thenCombine方法
CompletableFuture<String> f = future1.thenCombine(future2, (x,y) -> x+y);
System.out.println(f.get());
3.7 两任务组合–一个完成
/*以下方法的触发条件:--->之前的两个任务任意完成一个,开始执行本任务。A||B==1-->执行C的关系*/
//runAfterEither:不获取future结果,没有返回值
public CompletionStage<Void> runAfterEither(CompletionStage<?> other,Runnable action);
public CompletionStage<Void> runAfterEitherAsync(CompletionStage<?> other,Runnable action);
public CompletionStage<Void> runAfterEitherAsync(CompletionStage<?> other,Runnable action,Executor executor);
//acceptEither:获取完成了的那个future的结果,没有返回值
public CompletionStage<Void> acceptEither(CompletionStage<? extends T> other,Consumer<? super T> action);
public CompletionStage<Void> acceptEitherAsync(CompletionStage<? extends T> other,Consumer<? super T> action);
public CompletionStage<Void> acceptEitherAsync(CompletionStage<? extends T> other,Consumer<? super T> action,Executor executor);
//applyToEither:获取完成了的那个future的结果,并且有返回值
public <U> CompletionStage<U> applyToEither(CompletionStage<? extends T> other,Function<? super T, U> fn);
public <U> CompletionStage<U> applyToEitherAsync(CompletionStage<? extends T> other,Function<? super T, U> fn);
public <U> CompletionStage<U> applyToEitherAsync(CompletionStage<? extends T> other,Function<? super T, U> fn,Executor executor);
示例
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
return 100;
});
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
Thread.sleep(3000);
return -100;
});
/*-------------------------------------------------------------------------*/
//runAfterEithe方法
future1.runAfterEithe(future2,()->{
System.out.println("-------");
});
//acceptEither方法
future1.acceptEither(future2,(x) ->{
System.out.println(x);
});
//applyToEither方法
CompletableFuture<String> f = future1.applyToEither(future2, (x) -> x);
System.out.println(f.get());
3.8 多任务组合
//allOf:等待所有任务完成
public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)
//anyOf:只需要其中一个任务完成
public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs)
示例
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
return 1;
});
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
Thread.sleep(3000);
return 2;
});
CompletableFuture<Integer> f3 = CompletableFuture.supplyAsync(() -> {
Thread.sleep(3000);
return 3;
});
/*-------------------------------------------------------------------------*/
//allOf方法
CompletableFuture<Void> allOf = CompletableFuture.allOf(f1,f2,f3);
allOf.get();
System.out.println("都完成了");
//anyOf方法
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(f1,f2,f3);
anyOf.get();
System.out.println("完成的结果是-->"+anyOf.get());