当前位置: 首页 > 后端技术 > Java

关于CompletableFuture的一些知识

时间:2023-04-01 19:27:53 Java

Java1.5引入了Future,CompletableFuture是在1.8引入的。它的出现可以让我们更好的安排任务,合理的使用会大大减少多任务的处理时间,达到事半功倍的目的。下面我们就来看看与它相关的一些知识。1Java中的函数式编程查看CompletableFuture以了解一些Java中的函数式编程会更有用。@FunctionalInterface是Java1.8引入的,在java.util.function包中引入了很多函数式接口。看几个常见的:1.1ConsumerConsumer消费者,关联的方法是voidaccept(Tt),有参数,无返回值。@FunctionalInterfacepublicinterfaceConsumer{voidaccept(Tt);1.2FunctionFunction函数,关联方法为Rapply(Tt),有参数和返回值。@FunctionalInterfacepublicinterfaceFunction{Rapply(Tt);1.3PredicatePredicate谓词(assertion?),关联方法是booleantest(Tt),有参数和返回值(bool)。@FunctionalInterfacepublicinterfacePredicate{布尔测试(Tt);1.4SupplierSupplier供应商,关联方法为Tget(),无参数和返回值。@FunctionalInterfacepublicinterfaceSupplier{Tget();}2CompletableFuture后续内容将主要关注其内部的各种API。在后续的方法中,由于CompletableFuture实现了CompletionStage,所以具有链式调用的能力。大多数方法将类似于以下内容:xxx(Functionfunc):与上面相同的线程将执行当前任务xxxAsync(Functionfunc):将启动一个新线程来执行当前任务xxxAsync(Functionfunc,Executorexecutor):将使用executor线程池中的新线程执行当前任务2.1CompletableFuture创建supplyAsync:以Supplier为参数,有返回值。publicstaticCompletableFuturesupplyAsync(Suppliersupplier)publicstaticCompletableFuturesupplyAsync(Suppliersupplier,Executorexecutor)runAsync:以Runnable为参数,返回Void。publicstaticCompletableFuturerunAsync(Runnablerunnable)publicstaticCompletableFuturerunAsync(Runnablerunnable,Executorexecutor)completedFuture:创建一个已经具有值的完成的CompletableFuture。publicstaticCompletableFuturecompletedFuture(Uvalue)failedFuture:创建一个已完成但有异常的CompletableFuture。publicstaticCompletableFuturefailedFuture(Throwableex)可以看到runAsync和supplyAsync都额外提供了一个参数Exec??utor。当没有指定executor时,会默认使用ForkJoinPool.commonPool()来执行异步任务,而ParallelStream默认在某些情况下也会使用线程池。如果共享,可能会导致非核心业务抢占核心业务的执行。通常,自定义线程池用于执行这些任务。2.2CompletableFuture的后续操作2.2.1执行一个task(1)apply:有参数和返回值。之前的返回值将作为当前函数的输入。publicCompletableFuturethenApply(Functionfn)publicCompletableFuturethenApplyAsync(Functionfn)publicCompletableFuturethenApplyAsync(Functionfn,Executorexecutor)accept:有参数,无返回值。会将先前的输出作为当前函数的输入。publicCompletableFuturethenAccept(Consumeraction)publicCompletableFuturethenAcceptAsync(Consumeraction)publicCompletableFuturethenAcceptAsync(Consumeraction,Executor执行者)运行:编写另一个无关紧要的任务publicCompletableFuturethenRun(Runnableaction)publicCompletableFuturethenRunAsync(Runnableaction)publicCompletableFuturethenRunAsync(Runnableaction,Executorexecutor)示例@Testexceptionthrowvoid,InterruptedException{finalCompletableFuturefuture=CompletableFuture.supplyAsync(()->1).thenApply((val)->val+1);assertEquals(2,future.get());}@TestvoidtestAccept(){finalCompletableFuturefuture=CompletableFuture.supplyAsync(()->1).thenAccept((val)->{assertEquals(1,val);});future.join();}@TestvoidtestRun(){finalCompletableFuturefuture=CompletableFuture.supplyAsync(()->1).thenRun(()->{});future.join();}2.2.1执行一个任务(2)whenComplete:当任务完成时执行该方法,并将返回值和异常传递给BiConsumer(有参数但无返回值)publicCompletableFuturewhenComplete(BiConsumer动作)publicCompletableFuturewhenCompleteAsync(BiConsumeraction)publicCompletableFuturewhenCompleteAsync(BiConsumeraction,Executorexecutor)exceptionally:当任务发生异常时会调用相应的This方法,并将异常作为参数传入publicCompletableFutureexceptionally(Functionfn)publicCompletableFutureexceptionallyAsync(Functionfn)publicCompletableFutureexceptionallyAsync(Functionfn,Executor执行器)处理程序:接收并处理之前任务的结果BiFunction(带有参数和返回值)publicCompletableFuturehandle(BiFunctionfn)publicCompletableFuturehandleAsync(BiFunctionfn)publicCompletableFuturehandleAsync(BiFunctionfn,Executorexecutor)2.2.2执行两个任务之一即applyToEither:执行两个任务,无一例外地返回其中一个,并将输出作为参数传递给后续的Function(有参数和返回值)publicCompletableFutureapplyToEither(CompletionStageother,Functionfn)publicCompletableFutureapplyToEitherAsync(CompletionStageother,Functionfn)publicCompletableFutureapplyToEitherAsync(CompletionStageother,Functionfn,Executorexecutor)acceptEither:执行两个任务,无一例外地返回其中一个,并将输出作为参数传递给后续的Consumer(有参数但无返回值))公共完成ableFutureacceptEither(CompletionStageother,Consumeraction)publicCompletableFutureacceptEitherAsync(CompletionStageother,Consumeraction)publicCompletableFutureacceptEitherAsync(CompletionStageother,Consumeraction,Executorexecutor)runAfterEither:执行两个任务,无异常返回其中一个,并将输出作为参数传递给后续的Runnable(无参数,无返回值)publicCompletableFuturerunAfterEither(CompletionStageother,Runnableaction)publicCompletableFuturerunAfterEitherAsync(CompletionStageother,Runnableaction)publicCompletableFuturerunAfterEitherAsync(CompletionStageother,Runnableaction))Executorexecutor)2.2.3执行两个任务完成thenCombine:执行两个任务并将这两个任务作为参数输入到BiFunction中(带参数和返回值)publicCompletableFuturethenCombine(CompletionStage其他,BiFunctionfn)publicCompletableFuturethenCombineAsync(CompletionStageother,BiFunctionfn)publicCompletableFuturethenCombineAsync(CompletionStage<?无返回值)publicCompletableFuturethenAcceptBoth(CompletionStageother,BiConsumeraction)publicCompletableFuturethenAcceptBothAsync(CompletionStageother,BiConsumeraction)publicCompletableFuturethenAcceptBothAsync(CompletionStageother,BiConsumeraction,Executorexecutor)runAfterBoth:Execute两个任务,然后执行Runnable(无参数,无返回值)publicCompletableFuturerunAfterBoth(CompletionStageother,Runnableaction)publicCompletableFuturerunAfterBothAsync(CompletionStageother,Runnableaction)publicCompletableFuturerunAfterBothAsync(CompletionStageother,Runnableaction,Executor)2.2.4执行两个依赖任务thenCompose:前一个任务的结果应该作为参数给第二个任务publicCompletableFuturethenCompose(Function>fn)publicCompletableFuturethenComposeAsync(Function>fn)publicCompletableFuturethenComposeAsync(Function>fn,Executorexecutor)2.2.5合并更多任务allOf:等待所有任务完成publicstaticCompletableFutureallOf(CompletableFuture...cfs)anyOf:等待任何任务完成publicstaticCompletableFutureanyOf(可完成的未来...cfs)2.3结果获取2.3.1join任务完成时获取数据,或者出现异常时抛出异常。但是需要注意的是,它抛出的异常是(unchecked)异常,CancellationException或者CompletionExceptionpublicTjoin()2.3.2获取数据时:get()等待任务完成,然后读取结果;get(longtimeout,TimeUnitunit)在限定时间内等待读取结果完成,否则抛出TimeoutException;getNow(TvalueIfAbsent)立即获取结果,或者默认值;publicTget()throwsInterruptedException,ExecutionExceptionpublicTget(longtimeout,TimeUnitunit)throwsInterruptedException,ExecutionException,TimeoutExceptionpublicTgetNow(TvalueIfAbsent)3后记只有在正确的场景中使用它才能掌握。后面我们会结合实际场景讲一下如何使用它来进行任务编排。回声'5Y6f5Yib5paH56ugOiDmjpjph5Eo5L2g5oCO5LmI5Zad5aW26Iy25ZWKWzkyMzI0NTQ5NzU1NTA4MF0pL+aAneWQpihscGUyMzQp'|base64-d