1. CompletionStage接口
可能是异步计算的一个阶段,在另一个CompletionStage完成时执行操作或计算值。阶段在其计算结束时完成,但这可能反过来触发其他从属阶段。此界面中定义的功能仅采用几个基本形式,这些形式扩展到更大的方法集,以捕获一系列使用样式:
-
阶段执行的计算可以表示为Function、Consumer或Runnable(分别使用名称为apply、accept或run的方法),具体取决于它是否需要参数和/或产生结果。例如, stage.thenApply(x -> square(x)).thenAccept(x -> System.out.print(x)).thenRun(() -> System.out.println()). 。另一种形式(compose)应用阶段本身的功能,而不是它们的结果。
-
一个阶段的执行可以通过完成单个阶段、两个阶段或两个阶段中的任一个来触发。使用带有前缀then的方法排列对单个阶段的依赖关系。完成这两个阶段所触发的事件可以使用相应命名的方法组合其结果或效果。由两个阶段中的任何一个触发的结果都不能保证哪个结果或效果用于从属阶段的计算。
-
阶段之间的依赖性控制计算的触发,但不保证任何特定的顺序。此外,新阶段计算的执行可以以三种方式中的任何一种安排:默认执行、默认异步执行(使用后缀为async的方法,使用该阶段的默认异步执行工具)或自定义(通过提供的Executor)。默认和异步模式的执行属性由CompletionStage实现指定,而不是此接口。具有显式Executor参数的方法可能具有任意的执行属性,甚至可能不支持并发执行,但被安排为以适应异步的方式进行处理。
-
无论触发阶段是正常完成还是异常完成,两种方法形式都支持处理:method whenComplete允许注入动作,而不管结果如何,否则在完成时保留结果。方法句柄还允许该阶段计算替换结果,该替换结果可以由其他依赖阶段进行进一步处理。在所有其他情况下,如果一个阶段的计算突然终止,出现(未选中的)异常或错误,那么所有需要完成的从属阶段也会异常完成,CompletionException将异常作为其原因。如果一个阶段依赖于两个阶段,并且都异常完成,那么CompletionException可能对应于这些异常中的任一个。如果一个阶段依赖于其他两个阶段中的任何一个,并且只有其中一个阶段异常完成,则无法保证依赖阶段是正常完成还是异常完成。在方法whenComplete的情况下,当提供的操作本身遇到异常时,如果尚未异常完成,则阶段将异常完成,并出现此异常。
所有方法都遵守上述触发、执行和异常完成规范(在个别方法规范中不重复)。此外,尽管用于为接受它们的方法传递完成结果(即,对于类型为T的参数)的参数可能为空,但为任何其他参数传递空值将导致引发NullPointerException。
此接口不定义初始创建、强制正常或异常完成、探测完成状态或结果或等待阶段完成的方法。竣工阶段的实施可提供实现此类效果的方法(视情况而定)。方法toCompletableFuture通过提供一个通用的转换类型,支持此接口的不同实现之间的互操作性。
2. CompletableFuture类
可以显式完成的Future(设置其值和状态),并且可以用作CompletionStage,支持完成时触发的相关函数和操作。
当两个或多个线程尝试完成、完成异常或取消CompletableFuture时,只有一个线程成功。
除了直接操作状态和结果的这些方法和相关方法之外,CompletableFuture还使用以下策略实现了CompletionStage接口:
-
为非异步方法的依赖完成提供的操作可以由完成当前CompletableFuture的线程执行,也可以由完成方法的任何其他调用方执行。
-
所有没有显式Executor参数的异步方法都使用 ForkJoinPool.commonPool()(除非它不支持至少两个并行级别,在这种情况下,会创建一个新线程来运行每个任务)。为了简化监视、调试和跟踪,所有生成的异步任务都是标记接口CompletableFuture.AsynchronousCompletionTask的实例。
-
所有CompletionStage方法都是独立于其他公共方法实现的,因此一个方法的行为不会受到子类中其他方法的重写的影响。
CompletableFuture还实现了Future如下策略:
-
由于(与FutureTask不同)该类不能直接控制导致其完成的计算,因此取消被视为另一种形式的异常完成。方法cancel与completeExceptionly(new CancellationException())具有相同的效果。方法isCompletedExceptionally可用于确定CompletableFuture是否以任何异常方式完成。
-
在CompletionException异常完成的情况下,方法get()和get(long,TimeUnit)抛出一个ExecutionException,其原因与相应的CompletionExeption中的原因相同。为了简化在大多数上下文中的使用,该类还定义了join()和getNow方法来代替在这些情况下直接抛出CompletionException。
网友评论