
文章目录一. 合并两个异步任务的结果1. thenCombine()组合两个异步任务的结果2. runAfterBoth()在两个任务完成后执行无返回值操作3. thenAcceptBoth()消费两个任务的结果二. allOf()等待所有任务完成如果某个任务同时依赖另外两个异步任务的执行结果就需要对另外两个异步任务进行合并。以泡茶喝为例“泡茶喝”任务需要对“烧水”任务与“清洗”任务进行合并。对两个异步任务的合并可以通过CompletionStage接口的thenCombine()、runAfterBoth()、thenAcceptBoth()三个方法来实现。一. 合并两个异步任务的结果1.thenCombine()组合两个异步任务的结果thenCombine()方法允许我们同时处理两个异步任务的结果。当这两个任务都完成时它会执行一个BiFunction将两个任务的结果组合起来并返回一个新的CompletableFuture该CompletableFuture包含组合后的结果。使用场景当你有两个异步任务且需要同时使用它们的结果来进行某些操作时thenCombine()非常适合。示例代码CompletableFutureIntegerfuture1CompletableFuture.supplyAsync(()-2);CompletableFutureIntegerfuture2CompletableFuture.supplyAsync(()-3);future1.thenCombine(future2,(result1,result2)-result1result2).thenAccept(result-System.out.println(result));// 输出 5**分析**-future1 和 future2 是两个异步任务分别返回 2 和 3。-thenCombine() 会将这两个结果相加并返回 5。-thenAccept() 最终打印出 5。例子2TestpublicvoidthenCombineDemo()throwsException{CompletableFutureIntegerfuture1CompletableFuture.supplyAsync(newSupplierInteger(){OverridepublicIntegerget(){IntegerfirstStep1010;Print.tco(firstStep outcome is firstStep);returnfirstStep;}});CompletableFutureIntegerfuture2CompletableFuture.supplyAsync(newSupplierInteger(){OverridepublicIntegerget(){IntegersecondStep1010;Print.tco(secondStep outcome is secondStep);returnsecondStep;}});CompletableFutureIntegerfuture3future1.thenCombine(future2,newBiFunctionInteger,Integer,Integer(){OverridepublicIntegerapply(Integerstep1OutCome,Integerstep2OutCome){returnstep1OutCome*step2OutCome;}});Integerresultfuture3.get();Print.tco( outcome is result);}2.runAfterBoth()在两个任务完成后执行无返回值操作runAfterBoth()方法会在两个异步任务都完成后执行一个没有返回值的操作。与thenCombine()不同它不关心这两个任务的结果而是专注于在它们都完成后做某些操作比如记录日志、更新状态等。使用场景当你希望在两个异步任务都完成后执行某些副作用操作但不关心它们的计算结果时runAfterBoth()是最理想的选择。示例代码CompletableFutureIntegerfuture1CompletableFuture.supplyAsync(()-2);CompletableFutureIntegerfuture2CompletableFuture.supplyAsync(()-3);future1.runAfterBoth(future2,()-System.out.println(Both tasks completed));// 输出 Both tasks completed**分析**-runAfterBoth() 会在 future1 和 future2 都完成后执行无返回值的操作这里是打印出Both tasks completed。-重要的是它不会使用 future1 和 future2 的结果而仅在它们都完成时执行某个动作。3.thenAcceptBoth()消费两个任务的结果thenAcceptBoth()方法会在两个异步任务都完成后执行一个BiConsumer将这两个任务的结果作为参数传递给消费操作。它适用于在多个任务完成后需要处理这些结果的场景。使用场景当你希望在两个任务都完成时同时处理它们的结果但不需要返回任何新的结果时thenAcceptBoth()非常适用。示例代码CompletableFutureIntegerfuture1CompletableFuture.supplyAsync(()-2);CompletableFutureIntegerfuture2CompletableFuture.supplyAsync(()-3);future1.thenAcceptBoth(future2,(result1,result2)-System.out.println(Result1: result1, Result2: result2));// 输出 Result1: 2, Result2: 3**分析**-thenAcceptBoth() 会在 future1 和 future2 都完成后执行 BiConsumer并将两个任务的结果传入。-这里我们打印出 Result1:2 和 Result2:3显示了两个任务的计算结果。二.allOf()等待所有任务完成allOf()方法接受多个CompletableFuture作为参数并返回一个新的CompletableFutureVoid该CompletableFuture在所有输入的任务都完成时才完成。它通常用于等待多个异步任务全部完成并且不关心它们的结果。使用场景当你有多个异步任务并且你希望在它们都完成时继续执行某些操作而不需要关心每个任务的结果时可以使用allOf()。这是一个非常常用的场景特别是在执行多个独立的异步任务时。示例代码CompletableFutureIntegerfuture1CompletableFuture.supplyAsync(()-2);CompletableFutureIntegerfuture2CompletableFuture.supplyAsync(()-3);CompletableFutureIntegerfuture3CompletableFuture.supplyAsync(()-4);CompletableFutureVoidallOfCompletableFuture.allOf(future1,future2,future3);allOf.thenRun(()-System.out.println(All tasks are completed));// 输出 All tasks are completed**分析**-allOf() 会等待 future1、future2 和 future3 全部完成。-thenRun() 会在所有任务完成后执行并输出All tasks are completed。-需要注意的是allOf() 返回的 CompletableFutureVoid 不关心每个任务的计算结果只关注所有任务是否完成。thenRun用于在当前CompletableFuture完成后执行一个没有返回值的操作。它的作用类似于回调机制但不同于常规的回调函数thenRun()不接受任务的结果作为输入它只是执行一个副作用操作例如打印日志、更新状态等。例子2TestpublicvoidallOfDemo()throwsException{CompletableFutureVoidfuture1CompletableFuture.runAsync(()-Print.tco(模拟异步任务1));CompletableFutureVoidfuture2CompletableFuture.runAsync(()-Print.tco(模拟异步任务2));CompletableFutureVoidfuture3CompletableFuture.runAsync(()-Print.tco(模拟异步任务3));CompletableFutureVoidfuture4CompletableFuture.runAsync(()-Print.tco(模拟异步任务4));CompletableFutureVoidallCompletableFuture.allOf(future1,future2,future3,future4);all.join();}join()方法与get()类似但是它不会抛出InterruptedException或ExecutionException。相反如果任务失败join()会抛出CompletionException这意味着我们需要通过join()等待所有任务完成并且如果有任务失败CompletionException会包装抛出异常。