1、前言
学习java基础时候多线程使用我们首先学习的 Runable
、Future
、 Thread
、ExecutorService
、Callable
等相关类,在我们日常工作或者学习中有些场景并不满足我们需求,JDK8引入了一个新的类 CompletableFuture
来解决之前得问题, CompletableFuture
实现了 Future
接口和 CompletionStage
。因此 CompletableFuture是对 Futrue的功能增强包含了Future的功能。从继承的另一个 CompletionStage
的名称来看完成阶段性的接口,接下来了解一下 CompletableFuture
的一些基本情况以及使用和注意事项。
2、CompletableFuture使用
CompletableFuture提供了几十种方法,辅助我们的异步任务场景。这些方法包括创建异步任务、任务异步回调、多个任务组合处理等方面,JDK8设计出CompletableFuture。CompletableFuture提供了一种观察者模式类似的机制,可以让任务执行完成后通知监听的一方。
自定义线城池,一下代码都会使用到
static ExecutorService executor = Executors.newFixedThreadPool(3, new ThreadFactory() {int count = 1;@Overridepublic Thread newThread(Runnable runnable) {return new Thread(runnable, "completableFuture-executor-" + count++);}});
2.1创建异步任务
-
runAsync 用于构建一个没有入参也没有出参的任务;
-
supplyAsync 用于构建一个没有入参但是有出参的任务
runAsync和supplyAsync可以指定线程池,如果不指定,则使用ForkJoinPool的commonPool线程池
先看源码
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {return asyncSupplyStage(asyncPool, supplier);}public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor) {return asyncSupplyStage(screenExecutor(executor), supplier);}public static CompletableFuture<Void> runAsync(Runnable runnable) {return asyncRunStage(asyncPool, runnable);}public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor) {return asyncRunStage(screenExecutor(executor), runnable);}
runAsync执行CompletableFuture任务,没有返回值。
/*** runAsync执行CompletableFuture任务,没有返回值。*/public static void runAsyncExample() throws ExecutionException, InterruptedException {CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("异步线程执行执行结束");});System.out.println("异步线程执行状态" + completableFuture.isDone());System.out.println("主线程正在执行");System.out.println("异步线程执行状态" + completableFuture.isDone());System.out.println(completableFuture.get());}
执行结果
异步线程执行状态false
completableFuture-当前线程名称:ForkJoinPool.commonPool-worker-9
异步线程执行执行结束
null
supplyAsync执行CompletableFuture任务,支持返回值-使用自定义线城池
public static void supplyAsyncExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());System.out.println("异步线程执行执行结束");return "msg-异步线程执行结束";}, executor);System.out.println("主线程-------supplyAsyncExample-----正在执行");System.out.println(completableFuture.join());executor.shutdown(); // 线程池需要关闭}
执行结果
主线程-------supplyAsyncExample-----正在执行
completableFuture2-当前线程名称:completableFuture-executor-1
异步线程执行执行结束
msg-异步线程执行结束
2.2任务异步回调
2.2.1 thenRun/thenRunAsync
不关心上一个任务的执行返回结果,无参数,无返回值
CompletableFuture的thenRun方法,通俗点讲就是,做完第一个任务后,再做第二个任务。某个任务执行完成后,执行回调方法;但是前后两个任务没有参数传递,第二个任务也没有返回值
如果你执行第一个任务的时候,传入了一个自定义线程池:
- 调用thenRun方法执行第二个任务时,则第二个任务和第一个任务是共用同一个线程池。
- 调用thenRunAsync执行第二个任务时,则第一个任务使用的是你自己传入的线程池,第二个任务使用的是ForkJoin线程池
public CompletableFuture<Void> thenRun(Runnable action);
public CompletableFuture<Void> thenRunAsync(Runnable action);
thenRun代码
public static void thenRunExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("异步线程执行执行结束,当前线程"+Thread.currentThread().getName());return "msg-异步线程执行结束";}, executor);System.out.println("主线程-------thenRunExample-----正在执行1");CompletableFuture<Void> voidCompletableFuture = completableFuture.thenRun(() -> {System.out.println("thenRunExample----正在执行第二个任务,当前线程"+Thread.currentThread().getName());});System.out.println("主线程-------thenRunExample-----正在执行2");System.out.println(voidCompletableFuture.get());executor.shutdown(); // 线程池需要关闭}
执行结果
主线程-------thenRunExample-----正在执行1
主线程-------thenRunExample-----正在执行2
异步线程执行执行结束,当前线程completableFuture-executor-1
thenRunExample----正在执行第二个任务,当前线程completableFuture-executor-1
null
thenRunAsync代码-异步使用自定义线城池
public static void thenRunAsyncExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("异步线程执行执行结束---当前线城"+Thread.currentThread().getName());return "msg-异步线程执行结束";}, executor);System.out.println("主线程-------thenRunAsyncExample-----正在执行1");CompletableFuture<Void> voidCompletableFuture = completableFuture.thenRunAsync(() -> {System.out.println("thenRunExample----正在执行第二个任务---当前线城"+Thread.currentThread().getName());});System.out.println("主线程-------thenRunAsyncExample-----正在执行2");System.out.println(voidCompletableFuture.get());executor.shutdown(); // 线程池需要关闭}
执行结果
主线程-------thenRunAsyncExample-----正在执行1
主线程-------thenRunAsyncExample-----正在执行2
异步线程执行执行结束---当前线城completableFuture-executor-1
thenRunExample----正在执行第二个任务---当前线城ForkJoinPool.commonPool-worker-9
null
2.2.2.thenAccept/thenAcceptAsync
第一个任务执行完成后,执行第二个回调方法任务,会将该任务的执行结果,作为入参,传递到回调方法中,但是回调方法是没有返回值的。
thenAccept代码示例
public static void thenAcceptExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("异步线程执行执行结束--执行线程" + Thread.currentThread().getName());return "msg-异步线程执行结束";}, executor);System.out.println("主线程-------thenAcceptExample-----正在执行1");CompletableFuture<Void> voidCompletableFuture = completableFuture.thenAccept((msg) -> {System.out.println("thenAccept接受上一步返回参数" + msg);System.out.println("thenAcceptExample----正在执行第二个任务--执行线程" + Thread.currentThread().getName());});System.out.println("主线程-------thenAcceptExample-----正在执行2");System.out.println(voidCompletableFuture.get());executor.shutdown(); // 线程池需要关闭}
执行结果
主线程-------thenAcceptExample-----正在执行1
主线程-------thenAcceptExample-----正在执行2
异步线程执行执行结束--执行线程completableFuture-executor-1
thenAccept接受上一步返回参数msg-异步线程执行结束
thenAcceptExample----正在执行第二个任务--执行线程completableFuture-executor-1
null
thenAcceptAsync代码示例
public static void thenAcceptAsyncExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("异步线程执行执行结束---执行线程" + Thread.currentThread().getName());return "msg-异步线程执行结束";}, executor);System.out.println("主线程-------thenAcceptExample-----正在执行1");CompletableFuture<Void> voidCompletableFuture = completableFuture.thenAcceptAsync((msg) -> {System.out.println("thenAccept接受上一步返回参数" + msg);System.out.println("thenAcceptExample----正在执行第二个任务---执行线程" + Thread.currentThread().getName());}, executor);System.out.println("主线程-------thenAcceptExample-----正在执行2");System.out.println(voidCompletableFuture.get());executor.shutdown(); // 线程池需要关闭}
运行结果
主线程-------thenAcceptExample-----正在执行1
主线程-------thenAcceptExample-----正在执行2
异步线程执行执行结束---执行线程completableFuture-executor-1
thenAccept接受上一步返回参数msg-异步线程执行结束
thenAcceptExample----正在执行第二个任务---执行线程completableFuture-executor-2
null
2.2.3 thenApply/thenApplyAsync
第一个任务执行完成后,执行第二个回调方法任务,会将该任务的执行结果,作为入参,传递到回调方法中,并且回调方法是有返回值的
thenApply-不关心上一个任务的执行返回结果,有参数,有返回值-
代码
public static void thenApplyExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("异步线程执行执行结束---当前线程"+ Thread.currentThread().getName());return "msg-异步线程执行结束";}, executor);System.out.println("主线程-------thenApplyExample-----正在执行1");CompletableFuture<String> voidCompletableFuture = completableFuture.thenApply((msg) -> {System.out.println("thenApply接受上一步返回参数" + msg);System.out.println("thenApplyExample----正在执行第二个任务----当前线程"+ Thread.currentThread().getName());return "thenApplyExample执行任务结束";});System.out.println("主线程-------thenApplyExample-----正在执行2");System.out.println(voidCompletableFuture.get());executor.shutdown(); // 线池需要关闭}
执行结果
主线程-------thenApplyExample-----正在执行1
主线程-------thenApplyExample-----正在执行2
异步线程执行执行结束---当前线程completableFuture-executor-1
thenApply接受上一步返回参数msg-异步线程执行结束
thenApplyExample----正在执行第二个任务----当前线程completableFuture-executor-1
thenApplyExample执行任务结束
thenApplyAsync-任务异步回调-不关心上一个任务的执行返回结果,有参数,有返回值-
public static void thenApplyAsyncExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("异步线程执行执行结束");System.out.println("当前线程名称:" + Thread.currentThread().getName());return "msg-异步线程执行结束";}, executor);System.out.println("主线程-------thenApplyAsyncExample-----正在执行1");CompletableFuture<String> voidCompletableFuture = completableFuture.thenApplyAsync((msg) -> {System.out.println("thenApply接受上一步返回参数" + msg);System.out.println("当前线程名称:" + Thread.currentThread().getName());System.out.println("thenApplyAsyncExample----正在执行第二个任务");return "thenApplyAsyncExample执行任务结束";});System.out.println("主线程-------thenApplyAsyncExample-----正在执行2");System.out.println(voidCompletableFuture.get());executor.shutdown(); // 线池需要关闭}
执行结果
主线程-------thenApplyAsyncExample-----正在执行1
主线程-------thenApplyAsyncExample-----正在执行2
异步线程执行执行结束
当前线程名称:completableFuture-executor-1
thenApply接受上一步返回参数msg-异步线程执行结束
当前线程名称:ForkJoinPool.commonPool-worker-9
thenApplyAsyncExample----正在执行第二个任务
thenApplyAsyncExample执行任务结束
2.2.4 exceptionally-
某个任务执行异常时,执行的回调方法;并且有抛出异常作为参数,传递到回调方法。
执行代码
public static void exceptionallyExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("当前线程名称:" + Thread.currentThread().getName());throw new RuntimeException("咳咳!执行异常啦");}, executor);System.out.println("主线程-------exceptionallyExample-----正在执行1");CompletableFuture<String> voidCompletableFuture = completableFuture.exceptionally((throwable) -> {System.out.println("当前线程名称:" + Thread.currentThread().getName());System.out.println("exceptionallyExample----发生异常信息----" + throwable.getMessage());return "handleExample执行结束";});System.out.println("主线程-------exceptionallyExample-----正在执行2");System.out.println(voidCompletableFuture.get());executor.shutdown(); // 线池需关闭}
执行结果
主线程-------exceptionallyExample-----正在执行1
主线程-------exceptionallyExample-----正在执行2
当前线程名称:completableFuture-executor-1
当前线程名称:completableFuture-executor-1
exceptionallyExample----发生异常信息----java.lang.RuntimeException: 咳咳!执行异常啦
handleExample执行结束
2.2.5whenComplete/handle
whenComplete:某个任务执行完成后,执行的回调方法,无返回值;并且whenComplete方法返回的CompletableFuture的result是上个任务的结果。
handle:任务执行完成后,执行回调方法,并且是有返回值的;并且handle方法返回的CompletableFuture的result是回调方法执行的结果。
whenComplete 代码示例
public static void whenCompleteExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("异步线程执行执行结束--当前线程名称:" + Thread.currentThread().getName());return "msg-异步线程执行结束666";}, executor);System.out.println("主线程-------whenCompleteExample-----正在执行1");CompletableFuture<String> voidCompletableFuture = completableFuture.whenComplete((msg, throwable) -> {System.out.println("当前线程名称:" + Thread.currentThread().getName());System.out.println("whenCompleteExample----接受参数" + msg);});System.out.println("主线程-------whenCompleteExample-----正在执行2");System.out.println(voidCompletableFuture.get());executor.shutdown(); // 线池需要关闭}
执行结果
主线程-------whenCompleteExample-----正在执行1
主线程-------whenCompleteExample-----正在执行2
异步线程执行执行结束--当前线程名称:completableFuture-executor-1
当前线程名称:completableFuture-executor-1
whenCompleteExample----接受参数msg-异步线程执行结束666
msg-异步线程执行结束666
Handle 代码示例
public static void handleExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("异步线程执行执行结束");System.out.println("当前线程名称:" + Thread.currentThread().getName());return "msg-异步线程执行结束666";}, executor);System.out.println("主线程-------handleExample-----正在执行1");CompletableFuture<String> voidCompletableFuture = completableFuture.handle((msg, throwable) -> {System.out.println("当前线程名称:" + Thread.currentThread().getName());System.out.println("handleExample----接受参数" + msg);return "handleExample执行结束";});System.out.println("主线程-------handleExample-----正在执行2");System.out.println(voidCompletableFuture.get());executor.shutdown(); // 线池需要关闭}
执行结果
主线程-------handleExample-----正在执行1
主线程-------handleExample-----正在执行2
异步线程执行执行结束
当前线程名称:completableFuture-executor-1
当前线程名称:completableFuture-executor-1
handleExample----接受参数msg-异步线程执行结束666
handleExample执行结束
2.3 多个任务组合处理
2.3.1 thenCombine / thenAcceptBoth / runAfterBoth----AND组合关系
将两个CompletableFuture组合起来,只有这两个都正常执行完了,才会执行某个任务。
区别在于:
-
thenCombine:会将两个任务的执行结果作为方法入参,传递到指定方法中,且有返回值
-
thenAcceptBoth: 会将两个任务的执行结果作为方法入参,传递到指定方法中,且无返回值
-
runAfterBoth 不会把执行结果当做方法入参,且没有返回值。
thenCombine代码示列
public static void thenCombineExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());return "当前线程1执行结束";}, executor);CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());return "当前线程2执行结束";}, executor).thenCombine(completableFuture1, (msg1, msg2) -> {System.out.println("completableFuture1返回结果----" + msg1);System.out.println("completableFuture2返回结果----" + msg2);return "所有线程执行结束";});System.out.println("主线程-------thenCombineExample-----正在执行2");System.out.println(completableFuture2.join());executor.shutdown(); // 线池需关闭
}
执行结果
主线程-------thenCombineExample-----正在执行2
completableFuture1-当前线程名称:completableFuture-executor-1
completableFuture2-当前线程名称:completableFuture-executor-2
completableFuture1返回结果----当前线程2执行结束
completableFuture2返回结果----当前线程1执行结束
所有线程执行结束
thenAcceptBoth代码示例
public static void thenAcceptBothExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());return "当前线程1执行结束";});CompletableFuture<Void> completableFuture2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());return "当前线程2执行结束";}).thenAcceptBoth(completableFuture1, (msg1, msg2) -> {System.out.println("completableFuture1返回结果----" + msg1);System.out.println("completableFuture2返回结果----" + msg2);});System.out.println("主线程-------thenAcceptBothExample-----正在执行2");System.out.println(completableFuture2.join());executor.shutdown(); // 线池需关闭}
运行结果
主线程-------thenAcceptBothExample-----正在执行2
completableFuture1-当前线程名称:ForkJoinPool.commonPool-worker-9
completableFuture2-当前线程名称:ForkJoinPool.commonPool-worker-2
completableFuture1返回结果----当前线程2执行结束
completableFuture2返回结果----当前线程1执行结束
null
runAfterBoth代码示例
public static void runAfterBothExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());return "当前线程1执行结束";});CompletableFuture<Void> completableFuture2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());return "当前线程2执行结束";}).runAfterBoth(completableFuture1, () -> {System.out.println("两个线程都执行结束啦----");});System.out.println("主线程-------runAfterBothExample-----正在执行2");System.out.println(completableFuture2.join());executor.shutdown(); // 线池需关闭}
运行结果
主线程-------runAfterBothExample-----正在执行2
completableFuture2-当前线程名称:ForkJoinPool.commonPool-worker-2
completableFuture1-当前线程名称:ForkJoinPool.commonPool-worker-9
两个线程都执行结束啦----
null
2.3.2 applyToEither / acceptEither / runAfterEither ----OR组合关系
将两个CompletableFuture组合起来,只要其中一个执行完了,就会执行某个任务。
区别在于:
- applyToEither:会将已经执行完成的任务,作为方法入参,传递到指定方法中,且有返回值
- acceptEither: 会将已经执行完成的任务,作为方法入参,传递到指定方法中,且无返回值
- runAfterEither:不会把执行结果当做方法入参,且没有返回值。
applyToEither代码示例
public static void applyToEitherExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(101);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());return "当前线程1执行结束";});CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(10001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());return "当前线程2执行结束";}).applyToEither(completableFuture1, msg -> {return msg;});System.out.println("主线程-------thenCombineExample-----正在执行2");System.out.println(completableFuture2.join());executor.shutdown(); // 线池需关闭}
执行结果
主线程-------thenCombineExample-----正在执行2
completableFuture1-当前线程名称:ForkJoinPool.commonPool-worker-9
当前线程1执行结束
acceptEither代码示例
public static void acceptEitherExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());return "当前线程1执行结束";});CompletableFuture<Void> completableFuture2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(10001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());return "当前线程2执行结束";}).acceptEither(completableFuture1, msg -> {System.out.println("获取某线程返回参数------" + msg);});System.out.println("主线程-------acceptEitherExample-----正在执行2");System.out.println(completableFuture2.join());executor.shutdown(); // 线池需关闭}
执行结果
主线程-------acceptEitherExample-----正在执行2
completableFuture1-当前线程名称:ForkJoinPool.commonPool-worker-9
获取某线程返回参数------当前线程1执行结束
null
2.3.3AllOf/AnyOf 多个任务组合处理
3AllOf:所有任务都执行完成后,才执行 allOf返回的CompletableFuture。如果任意一个任务异常,allOf的CompletableFuture,执行get方法,会抛出异常
AnyOf:任意一个任务执行完,就执行anyOf返回的CompletableFuture。如果执行的任务异常,anyOf的CompletableFuture,执行get方法,会抛出异常
AllOf代码示例
/*** 多个任务组合处理* 所有任务都执行完成后,才执行 allOf返回的CompletableFuture。如果任意一个任务异常,allOf的CompletableFuture,执行get方法,会抛出异常 *** @throws ExecutionException* @throws InterruptedException*/public static void allOfExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());return "当前线程1执行结束";});CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());
// throw new RuntimeException("咳咳!执行异常啦");return "当前线程2执行结束";});CompletableFuture<Void> completableFuture = CompletableFuture.allOf(completableFuture1, completableFuture2).whenComplete((msg1, msg2) -> {System.out.println("allOf----所有线程执行结束---" + msg1);System.out.println("allOf----所有线程执行结束---" + msg2);});System.out.println("主线程-------acceptEitherExample-----正在执行2");System.out.println(completableFuture.get());}
执行结果
主线程-------acceptEitherExample-----正在执行2
completableFuture1-当前线程名称:ForkJoinPool.commonPool-worker-9
completableFuture2-当前线程名称:ForkJoinPool.commonPool-worker-2
allOf----所有线程执行结束---null
allOf----所有线程执行结束---null
null
AnyOf代码示例
public static void anyOfExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());return "当前线程1执行结束";});CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1001);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());return "当前线程2执行结束";});CompletableFuture<Object> completableFuture = CompletableFuture.anyOf(completableFuture1, completableFuture2).whenComplete((msg1, msg2) -> {System.out.println("anyOf----所有线程执行结束---" + msg1);System.out.println("anyOf----所有线程执行结束---" + msg2);});System.out.println("主线程-------anyOfExample-----正在执行2");System.out.println(completableFuture.get());}
运行结果
主线程-------anyOfExample-----正在执行2
completableFuture1-当前线程名称:ForkJoinPool.commonPool-worker-9
completableFuture2-当前线程名称:ForkJoinPool.commonPool-worker-2
anyOf----所有线程执行结束---当前线程1执行结束
anyOf----所有线程执行结束---null
当前线程1执行结束
2.3.4thenCompose
thenCompose方法会在某个任务执行完成后,将该任务的执行结果,作为方法入参,去执行指定的方法。该方法会返回一个新的CompletableFuture实例
是对另一个CompletableFuture进行计算、操作,也就是说用来连接两个CompletableFuture,是生成一个新的CompletableFuture。
代码示例
public static void thenComposeExample() throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());return "当前线程1执行结束";},executor).thenCompose(result -> CompletableFuture.supplyAsync(() -> {System.out.println(result + "当前线程2执行结束-当前线程名称:" + Thread.currentThread().getName());return result + "当前线程2执行结束";},executor));System.out.println(completableFuture1.get());}
执行结果
completableFuture1-当前线程名称:completableFuture-executor-1
当前线程1执行结束当前线程2执行结束-当前线程名称:completableFuture-executor-2
当前线程1执行结束当前线程2执行结束