Java 9 CompletableFuture API 改进-Java快速进阶教程
1. 简介
Java 9对CompletableFuture类进行了一些更改。这些更改是作为JEP 266的一部分引入的,目的是解决自 JDK 8 中引入以来常见的抱怨和建议,更具体地说,支持延迟和超时,更好地支持子类化和一些实用程序方法。
在代码方面,API 附带了八个新方法和五个新的静态方法。为了启用此类添加,大约更改了 2400 行代码中的 1500 行(根据 Open JDK)。
2. 实例新添加的API
如前所述,实例 API 附带了八个新增功能,它们是:
- Executor defaultExecutor()
- CompletableFuture<U> newIncompleteFuture()
- CompletableFuture<T> copy()
- CompletionStage<T> minimalCompletionStage()
- CompletableFuture<T> completeAsync(Supplier<? extends T> supplier, Executor executor)
- CompletableFuture<T> completeAsync(Supplier<? extends T> supplier)
- CompletableFuture<T> orTimeout(long timeout, TimeUnit unit)
- CompletableFuture<T> completeOnTimeout(T value, long timeout, TimeUnit unit)
2.1. defaultExecutor()
签名:Executor defaultExecutor()
返回用于未指定执行程序的异步方法的默认Executor。
new CompletableFuture().defaultExecutor()
这可以通过返回至少提供一个独立线程的Executor的子类来覆盖。
2.2. newIncompleteFuture()
签名:CompletableFuture<U> newIncompleteFuture()
newIncompleteFuture,也称为“虚拟构造函数”,用于获取相同类型的新可完成未来实例。
new CompletableFuture().newIncompleteFuture()
此方法在子类化CompletableFuture 时特别有用,主要是因为它在几乎所有返回新CompletionStage 的方法中内部使用,允许子类控制这些方法返回的子类型。
2.3. copy()
签名:CompletableFuture<T> copy()
这个方法返回一个新的CompletableFuture:
当这个正常完成时,新的也正常完成
当它以异常X异常完成时,新的一个也以异常完成,并以X作为原因的CompletionException
new CompletableFuture().copy()
此方法可能用作“防御性复制”的一种形式,以防止客户端完成,同时仍然能够在CompletableFuture 的特定实例上安排依赖操作。
2.4. minimalCompletionStage()
签名:CompletionStage<T> minimalCompletionStage()
此方法返回一个新的CompletionStage,其行为方式与复制方法描述的方式完全相同,但是,此类新实例在每次尝试检索或设置解析值时都会引发UnsupportedOperationException。
new CompletableFuture().minimalCompletionStage()
可以使用CompletionStageAPI 上提供的toCompletableFuture方法检索包含所有可用方法的新CompletableFuture。
2.5. completeAsync()
应使用 completeAsync方法,使用供应商提供的值异步完成CompletableFuture。
签名:
CompletableFuture<T> completeAsync(Supplier<? extends T> supplier, Executor executor)
CompletableFuture<T> completeAsync(Supplier<? extends T> supplier)
这两个重载方法之间的区别在于存在第二个参数,可以在其中指定运行任务的执行器。如果未提供任何内容,则将使用默认执行器(由defaultExecutor方法返回)。
2.6. orTimeout()
签名:CompletableFuture<T> orTimeout(long timeout, TimeUnit unit)
new CompletableFuture().orTimeout(1, TimeUnit.SECONDS)
使用TimeoutException 异常解析CompletableFuture,除非它在指定的超时之前完成。
2.7.completeOnTimeout()
签名:CompletableFuture<T> completeOnTimeout(T value, long timeout, TimeUnit unit)
new CompletableFuture().completeOnTimeout(value, 1, TimeUnit.SECONDS)
使用指定的值正常完成CompletableFuture,除非它在指定的超时之前完成。
3. 静态 API 添加
还添加了一些实用程序方法。它们是:
- Executor delayedExecutor(long delay, TimeUnit unit, Executor executor)
- Executor delayedExecutor(long delay, TimeUnit unit)
- <U> CompletionStage<U> completedStage(U value)
- <U> CompletionStage<U> failedStage(Throwable ex)
- <U> CompletableFuture<U> failedFuture(Throwable ex)
3.1. delayedExecutor
签名:
Executor delayedExecutor(long delay, TimeUnit unit, Executor executor)
Executor delayedExecutor(long delay, TimeUnit unit)
返回一个新的执行程序,该执行程序在给定延迟后(如果为非正值,则无延迟)向给定的基本执行程序提交任务。每个延迟在调用返回的执行程序的执行方法时开始。如果未指定执行器,则将使用默认执行器(ForkJoinPool.commonPool())。
3.2. completedStage 与failedStage
签名:
<U> CompletionStage<U> completedStage(U value)
<U> CompletionStage<U> failedStage(Throwable ex)
此实用工具方法返回已解析的CompletionStage实例,这些实例要么正常完成,但有值 (completeStage),要么异常完成(failedStage),但出现给定的异常。
3.3. failedFuture
签名:<U> CompletableFuture<U> failedFuture(Throwable ex)
failedFuture 方法添加了指定已完成的异常CompleatebleFuture实例的功能。
4. 示例用例
在本节中,我们将展示一些有关如何使用一些新 API 的示例。
4.1. Delay
此示例将展示如何将具有特定值的CompletableFuture的完成延迟一秒。这可以通过将completeAsync方法与delayedExecutor 一起使用来实现。
CompletableFuture<Object> future = new CompletableFuture<>();
future.completeAsync(() -> input, CompletableFuture.delayedExecutor(1, TimeUnit.SECONDS));
4.2. completeOnTimeout
实现延迟结果的另一种方法是使用completeOnTimeout方法。此示例定义了一个CompletableFuture,如果给定输入在 1 秒后仍未解析,则将使用该输入进行解析。
CompletableFuture<Object> future = new CompletableFuture<>();
future.completeOnTimeout(input, 1, TimeUnit.SECONDS);
4.3. Timeout
另一种可能性是超时,它使用TimeoutException 异常地解决未来问题。例如,让CompletableFuture在 1 秒后超时,给定它在此之前不会完成。
CompletableFuture<Object> future = new CompletableFuture<>();
future.orTimeout(1, TimeUnit.SECONDS);
5. 结论
总之,Java 9 对CompletableFutureAPI 进行了一些补充,它现在对子类化有了更好的支持,这要归功于新的 IncompleteFuture虚拟构造函数,可以控制大多数 CompletionStage API 中返回的CompletionStage实例。
如前所述,它肯定对延迟和超时有更好的支持。添加的实用程序方法遵循合理的模式,为CompletableFuture提供了一种指定已解析实例的便捷方法。