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つの新しい追加があります。
-
Executor defaultExecutor()
-
CompletableFuture <U> newIncompleteFuture()
-
CompletableFuture <T> copy()
-
CompletionStage <T> minimalCompletionStage()
-
__CompletableFuture <T> completeAsync(サプライヤ<?extends T>サプライヤ、
エグゼキュータエグゼキュータ)__
。 CompletableFuture <T> completeAsync(サプライヤ<?extends T>サプライヤ)
-
CompletableFuture <T>またはTimeout(長いタイムアウト、TimeUnit単位)
-
__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の追加
いくつかのユーティリティメソッドも追加されました。彼らです:
-
__Executor delayedExecutor(長い遅延、TimeUnit単位、Executor
エグゼキュータ)
。
Executor delayedExecutor(長い遅延、TimeUnit単位)__
-
<U> CompletionStage <U> completedStage(U値)
-
<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)
指定された遅延の後、指定されたベースエグゼキュータにタスクを送信する新しい
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]
リポジトリ
。