Java 9 CompletableFuture APIの改善

1前書き

Java 9では、 CompletableFuture クラスにいくつかの変更が加えられています。このような変更は、JDK 8での導入以降の共通の苦情や提案、具体的には遅延とタイムアウトのサポート、より良いサポートに対処するためにhttp://openjdk.java.net/jeps/266[JEP 266]の一部として導入されましたサブクラス化といくつかのユーティリティメソッドのために。

コード面では、APIには8つの新しいメソッドと5つの新しい静的メソッドがあります。このような追加を可能にするために、2400行のコードのうち約1500行が変更されました(Open JDKによる)。

2インスタンスAPIの追加

前述のように、インスタンスAPIには8つの新しい追加があります。

  1. Executor defaultExecutor()

  2. CompletableFuture <U> newIncompleteFuture()

  3. CompletableFuture <T> copy()

  4. CompletionStage <T> minimalCompletionStage()

  5. __CompletableFuture <T> completeAsync(サプライヤ<?extends T>サプライヤ、

エグゼキュータエグゼキュータ)__ 。 CompletableFuture <T> completeAsync(サプライヤ<?extends T>サプライヤ)

  1. CompletableFuture <T>またはTimeout(長いタイムアウト、TimeUnit単位)

  2. __CompletableFuture <T> completeOnTimeout(T値、長いタイムアウト、

TimeUnitの単位)__

2.1. メソッド defaultExecutor()

  • 署名** : Executor defaultExecutor()

Executor を指定しない非同期メソッドに使用されるデフォルトの Executor を返します。

new CompletableFuture().defaultExecutor()

これは、少なくとも1つの独立したスレッドを提供するエクゼキュータを返すサブクラスによってオーバーライドされる可能性があります。

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()

このメソッドは、copyメソッドとまったく同じ方法で動作する新しい CompletionStage を返しますが、解決された値を取得または設定しようとするたびに UnsupportedOperationException がスローされます。

new CompletableFuture().minimalCompletionStage()

利用可能なすべてのメソッドを含む新しい CompletableFuture は、 CompletionStage APIで利用可能な toCompletableFuture メソッドを使用して取得できます。

2.5. メソッド completeAsync()

completeAsync メソッドを使用して、提供された Supplier で指定された値を使用して CompletableFuture を非同期的に完了する必要があります。

  • 署名** :

CompletableFuture<T> completeAsync(Supplier<? extends T> supplier, Executor executor)
CompletableFuture<T> completeAsync(Supplier<? extends T> supplier)

この2つのオーバーロードメソッドの違いは、タスクを実行している Executor を指定できる2番目の引数の存在です。何も指定されていない場合は、デフォルトのexecutor( defaultExecutor メソッドによって返される)が使用されます。

2.6. メソッド orTimeout()

  • 署名** : CompletableFuture <T>またはTimeout(長いタイムアウト、TimeUnit単位)

new CompletableFuture().orTimeout(1, TimeUnit.SECONDS)

指定されたタイムアウトの前に完了しない限り、 CompletableFuture TimeoutException で例外的に解決します。

2.7. メソッド completeOnTimeout()

  • 署名** : CompletableFuture <T> completeOnTimeout(T値、長いタイムアウト、TimeUnit単位)

new CompletableFuture().completeOnTimeout(value, 1, TimeUnit.SECONDS)

指定されたタイムアウト前に完了しない限り、 CompletableFuture を通常は指定された値で完了します。

3静的APIの追加

いくつかのユーティリティメソッドも追加されました。彼らです:

  1. __Executor delayedExecutor(長い遅延、TimeUnit単位、Executor

エグゼキュータ) Executor delayedExecutor(長い遅延、TimeUnit単位)__

  1. <U> CompletionStage <U> completedStage(U値)

  2. <U> CompletionStage <U> failedStage(Throwable ex)

  3. <U> CompletableFuture <U> failedFuture(Throwable ex)

3.1. メソッド delayedExecutor

  • 署名** :

Executor delayedExecutor(long delay, TimeUnit unit, Executor executor)
Executor delayedExecutor(long delay, TimeUnit unit)

指定された遅延の後、指定されたベースエグゼキュータにタスクを送信する新しい Executor を返します(正でない場合は遅延なし)。それぞれの遅延は、返されたエグゼキュータのexecuteメソッドが呼び出されたときに始まります。 executorが指定されていない場合は、デフォルトのexecutor( ForkJoinPool.commonPool() )が使用されます。

3.2. メソッド completedStage および failedStage

  • 署名** :

<U> CompletionStage<U> completedStage(U value)
<U> CompletionStage<U> failedStage(Throwable ex)

このユーティリティメソッドは、解決済みの CompletionStage インスタンスを返します。通常は値( completedStage )で完了するか、特定の例外が発生した( failedStage )で完了します。

3.3. メソッド failedFuture

  • 署名** : <U> CompletableFuture <U> failedFuture(Throwable ex)

failedFutureメソッドは、すでに完了した例外的に CompleatebleFuture インスタンスを指定する機能を追加します。

4ユースケースの例

このセクションでは、新しいAPIの使い方の例をいくつか示します。

4.1. ディレイ

この例は、特定の値を持つ CompletableFuture の完了を1秒遅らせる方法を示します。これは completeAsync メソッドと delayedExecutor を併用することで実現できます。

CompletableFuture<Object> future = new CompletableFuture<>();
future.completeAsync(() -> input, CompletableFuture.delayedExecutor(1, TimeUnit.SECONDS));

4.2. タイムアウト時の値で完了

遅延した結果を得るためのもう1つの方法は、 completeOnTimeout メソッドを使用することです。この例は CompletableFuture を定義します。これは、1秒後に未解決のままであれば、指定された入力で解決されます。

CompletableFuture<Object> future = new CompletableFuture<>();
future.completeOnTimeout(input, 1, TimeUnit.SECONDS);

4.3. タイムアウト

もう一つの可能​​性は TimeoutException で例外的に未来を解決するタイムアウトです。たとえば、 CompletableFuture が1秒後にタイムアウトしたとしても、その前には完了しません。

CompletableFuture<Object> future = new CompletableFuture<>();
future.orTimeout(1, TimeUnit.SECONDS);

5結論

結論として、Java 9は CompletableFuture APIにいくつか追加されています。これは、 newIncompleteFuture 仮想コンストラクタのおかげでサブクラス化のサポートが改善され、ほとんどの CompletionStage APIで返される CompletionStage インスタンスを制御することができます。

確かに、前に示したように遅延とタイムアウトをよりよくサポートしています。追加されたユーティリティメソッドは賢明なパターンに従い、 CompletableFuture に解決されたインスタンスを指定する便利な方法を与えます。

この記事で使用されている例はhttps://github.com/eugenp/tutorials/tree/master/core-java-9[GitHub] リポジトリ