1. 序章

Java 9には、CompleteableFutureクラスにいくつかの変更が加えられています。 このような変更は、JDK 8での導入以降の一般的な苦情や提案に対処するために、 JEP 266 の一部として導入されました。具体的には、遅延とタイムアウトのサポート、サブクラス化のサポートの向上、およびいくつかのユーティリティメソッドです。

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

2. インスタンスAPIの追加

前述のように、インスタンスAPIには8つの新しい追加機能があります。それらは次のとおりです。

  1. エグゼキュータdefaultExecutor()
  2. CompletableFuture newIncompleteFuture()
  3. CompletableFuture コピー()
  4. CompletionStage minimumCompletionStage()
  5. CompletableFuture completeAsync(Supplier <? T>サプライヤー、エグゼキューターエグゼキューターを拡張します)
  6. CompletableFuture completeAsync(Supplier <? T>サプライヤーを拡張します)
  7. CompletableFuture orTimeout(長いタイムアウト、TimeUnitユニット)
  8. CompletableFuture completeOnTimeout(T値、長いタイムアウト、TimeUnit単位)

2.1. メソッドdefaultExecutor()

署名 Executor defaultExecutor()

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

new CompletableFuture().defaultExecutor()

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

2.2. メソッドnewIncompleteFuture()

サイン CompletableFuture newIncompleteFuture()

newIncompleteFuture は、「仮想コンストラクター」とも呼ばれ、同じタイプの新しい完了可能な将来のインスタンスを取得するために使用されます。

new CompletableFuture().newIncompleteFuture()

このメソッドは、 CompleteableFuture をサブクラス化する場合に特に役立ちます。これは、主に、新しい CompletionStage を返すほとんどすべてのメソッドで内部的に使用され、サブクラスがそのようなメソッドによって返されるサブタイプを制御できるようにするためです。

2.3. メソッドcopy()

サイン CompletableFuture コピー()

このメソッドは、新しいCompleteableFutureを返します。

  • これが正常に完了すると、新しいものも正常に完了します
  • これが例外Xを除いて例外的に完了すると、新しいものも CompleteException を使用して例外的に完了し、Xが原因になります。
new CompletableFuture().copy()

このメソッドは、 CompleteableFuture の特定のインスタンスに依存するアクションを配置できる一方で、クライアントが完了しないようにするための「防御コピー」の形式として役立つ場合があります。

2.4. メソッドminimalCompletionStage()

サイン CompletionStage minimumCompletionStage()

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

new CompletableFuture().minimalCompletionStage()

CompleteStageAPIで使用可能なtoCompletableFutureメソッドを使用して、すべてのメソッドを使用できる新しいCompleteableFutureを取得できます。

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番目の引数の存在です。 何も指定されていない場合は、デフォルトのエグゼキュータ( defaultExecutor メソッドによって返される)が使用されます。

2.6. メソッドorTimeout()

サイン CompletableFuture orTimeout(長いタイムアウト、TimeUnitユニット)

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

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

2.7. メソッドcompleteOnTimeout()

サイン CompletableFuture completeOnTimeout(T値、長いタイムアウト、TimeUnit単位)

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

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

3. 静的APIの追加

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

  1. エグゼキュータdelayedExecutor(長い遅延、TimeUnitユニット、エグゼキュータエグゼキュータ)
  2. エグゼキュータdelayedExecutor(長い遅延、TimeUnit単位)
  3. CompletionStagecompletedStage (U値)
  4. CompletionStage failedStage(Throwable ex)
  5. CompletableFuture failedFuture(Throwable ex)

3.1. メソッドdelayedExecutor

署名

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

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

3.2. メソッドcompletedStageおよびfailedStage

署名

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

このユーティリティメソッドは、すでに解決された CompleteStage インスタンスを返します。これは、値( completeStage )で正常に完了するか、指定された例外を除いて例外的に完了( failedStage )します。

3.3. メソッドfailedFuture

サイン CompletableFuture failedFuture(Throwable ex)

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

4. ユースケースの例

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

4.1. 遅れ

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

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

4.2. タイムアウト時に値で完了する

遅延結果を実現する別の方法は、completeOnTimeoutメソッドを使用することです。 この例では、 CompleteableFuture を定義します。これは、1秒後に未解決のままである場合に、特定の入力で解決されます。

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

4.3. タイムアウト

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

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

5. 結論

結論として、Java9にはCompletableFuture APIにいくつかの追加機能があり、 newIncompleteFuture 仮想コンストラクターのおかげで、サブクラス化のサポートが向上し、を制御できるようになりました。ほとんどのCompletionStageAPIで返されるX237X]CompletionStageインスタンス。

前に示したように、間違いなく、遅延とタイムアウトのサポートが向上しています。 追加されたユーティリティメソッドは賢明なパターンに従い、CompleteableFutureに解決されたインスタンスを指定する便利な方法を提供します。

この記事で使用されている例は、GitHubリポジトリにあります。