Java 9 CompletableFuture-API-Verbesserungen

Java 9 CompletableFuture API-Verbesserungen

1. Einführung

Java 9 enthält einige Änderungen an der KlasseCompletableFuture. Solche Änderungen wurden als Teil vonJEP 266 eingeführt, um häufige Beschwerden und Vorschläge seit seiner Einführung in JDK 8 zu berücksichtigen, insbesondere Unterstützung für Verzögerungen und Zeitüberschreitungen, bessere Unterstützung für Unterklassen und einige nützliche Methoden.

In Bezug auf den Code enthält die API acht neue Methoden und fünf neue statische Methoden. Um solche Ergänzungen zu ermöglichen, wurden ungefähr 1500 von 2400 Codezeilen geändert (gemäß Open JDK).

2. Instanz-API-Ergänzungen

Wie bereits erwähnt, enthält die Instanz-API acht neue Ergänzungen:

  1. Executor defaultExecutor ()

  2. CompletableFuture newIncompleteFuture ()

  3. CompletableFuture copy ()

  4. CompletionStage minimalCompletionStage ()

  5. CompletableFuture completeAsync (Supplier Lieferant, Executor Executor)

  6. CompletableFuture completeAsync (Supplier Lieferant)

  7. CompletableFuture oder Timeout (lange Zeitüberschreitung, TimeUnit-Einheit)

  8. CompletableFuture completeOnTimeout (T-Wert, lange Zeitüberschreitung, TimeUnit-Einheit)

2.1. MethodedefaultExecutor()

Signature:Executor defaultExecutor()

Gibt die StandardwerteExecutorzurück, die für asynchrone Methoden verwendet werden, die keineExecutorangeben.

new CompletableFuture().defaultExecutor()

Dies kann überschrieben werden, indem Unterklassen einen Executor zurückgeben, der mindestens einen unabhängigen Thread bereitstellt.

2.2. MethodenewIncompleteFuture()

Signature:CompletableFuture<U> newIncompleteFuture()

DasnewIncompleteFuture, auch als "virtueller Konstruktor" bekannt, wird verwendet, um eine neue abschließbare zukünftige Instanz desselben Typs abzurufen.

new CompletableFuture().newIncompleteFuture()

Diese Methode ist besonders nützlich, wennCompletableFuture in Unterklassen unterteilt werden, hauptsächlich weil sie intern in fast allen Methoden verwendet wird, die neueCompletionStage zurückgeben, sodass Unterklassen steuern können, welcher Subtyp von solchen Methoden zurückgegeben wird.

2.3. Methodecopy()

Signature:CompletableFuture<T> copy()

Diese Methode gibt ein neuesCompletableFuture zurück, das:

  • Wenn dies normal abgeschlossen wird, wird das neue auch normal abgeschlossen

  • Wenn dies ausnahmsweise mit Ausnahme X abgeschlossen wird, wird die neue auch ausnahmsweise mitCompletionException mit X als Ursache abgeschlossen

new CompletableFuture().copy()

Diese Methode kann als eine Form des "defensiven Kopierens" nützlich sein, um zu verhindern, dass Clients abgeschlossen werden, und gleichzeitig abhängige Aktionen für eine bestimmte Instanz vonCompletableFuture arrangieren können.

2.4. MethodeminimalCompletionStage()

Signature:CompletionStage<T> minimalCompletionStage()

Diese Methode gibt ein neuesCompletionStage zurück, das sich genauso verhält wie von der Kopiermethode beschrieben. Eine solche neue Instanz löst jedochUnsupportedOperationException bei jedem Versuch aus, den aufgelösten Wert abzurufen oder festzulegen.

new CompletableFuture().minimalCompletionStage()

Ein neuesCompletableFuture mit allen verfügbaren Methoden kann mithilfe dertoCompletableFuture-Methode abgerufen werden, die in derCompletionStage-API verfügbar ist.

2.5. MethodencompleteAsync()

Die MethodecompleteAsync sollte verwendet werden, umCompletableFuture asynchron unter Verwendung des durch die angegebenenSupplier angegebenen Werts zu vervollständigen.

Signatures:

CompletableFuture completeAsync(Supplier supplier, Executor executor)
CompletableFuture completeAsync(Supplier supplier)

Der Unterschied zwischen diesen beiden überladenen Methoden besteht in der Existenz des zweiten Arguments, in dem dieExecutorangegeben werden können, auf denen die Aufgabe ausgeführt wird. Wenn keine angegeben ist, wird der Standard-Executor (von derdefaultExecutor-Methode zurückgegeben) verwendet.

2.6. MethodenorTimeout()

Signature:CompletableFuture<T> orTimeout(long timeout, TimeUnit unit)

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

Löst dieCompletableFuture ausnahmsweise mitTimeoutException auf, es sei denn, sie werden vor dem angegebenen Zeitlimit abgeschlossen.

2.7. MethodecompleteOnTimeout()

Signature:CompletableFuture<T> completeOnTimeout(T value, long timeout, TimeUnit unit)

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

Vervollständigt dieCompletableFuture normalerweise mit dem angegebenen Wert, es sei denn, sie werden vor dem angegebenen Zeitlimit abgeschlossen.

3. Statische API-Ergänzungen

Einige Dienstprogrammmethoden wurden ebenfalls hinzugefügt. Sie sind:

  1. Executor verzögertExecutor (lange Verzögerung, TimeUnit-Einheit, Executor Executor)

  2. Executor verzögertExecutor (lange Verzögerung, TimeUnit-Einheit)

  3. CompletionStage completeStage (U-Wert)

  4. CompletionStage failedStage (Throwable ex)

  5. CompletableFuture failedFuture (Throwable ex)

3.1. MethodendelayedExecutor

Signatures:

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

Gibt ein neuesExecutor zurück, das nach der angegebenen Verzögerung eine Aufgabe an den angegebenen Basis-Executor sendet (oder keine Verzögerung, wenn sie nicht positiv ist). Jede Verzögerung beginnt mit dem Aufruf der Ausführungsmethode des zurückgegebenen Executors. Wenn kein Executor angegeben ist, wird der Standard-Executor (ForkJoinPool.commonPool()) verwendet.

3.2. MethodencompletedStage undfailedStage

Signatures:

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

Diese Dienstprogrammmethoden geben bereits aufgelösteCompletionStage-Instanzen zurück, die entweder normal mit einem Wert (completedStage) oder ausnahmsweise (failedStage) mit der angegebenen Ausnahme abgeschlossen wurden.

3.3. MethodefailedFuture

Signature:<U> CompletableFuture<U> failedFuture(Throwable ex)

Die Methode failedFuture bietet die Möglichkeit, eine bereits abgeschlossene Instanz vonCompleatebleFuturein Ausnahmefällen anzugeben.

4. Beispielanwendungsfälle

In diesem Abschnitt werden einige Beispiele für die Verwendung einiger neuer APIs gezeigt.

4.1. Verzögern

Dieses Beispiel zeigt, wie Sie die Fertigstellung vonCompletableFuture mit einem bestimmten Wert um eine Sekunde verzögern können. Dies kann erreicht werden, indem die MethodecompleteAsync zusammen mit der MethodedelayedExecutor verwendet wird.

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



4.2. Vervollständigen Sie mit Value on Timeout

Eine andere Möglichkeit, ein verzögertes Ergebnis zu erzielen, ist die Verwendung dercompleteOnTimeout-Methode. In diesem Beispiel wird einCompletableFuture definiert, das mit einer bestimmten Eingabe aufgelöst wird, wenn es nach 1 Sekunde nicht aufgelöst wird.

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



4.3. Auszeit

Eine andere Möglichkeit ist das Timeout, das die Zukunft ausnahmsweise mitTimeoutException auflöst. Wenn beispielsweise das Zeitlimit vonCompletableFuturenach 1 Sekunde abgelaufen ist, ist es vorher nicht abgeschlossen.

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





5. Fazit

Zusammenfassend lässt sich sagen, dass Java 9 mehrere Ergänzungen zurCompletableFuture-API enthält. Dank des virtuellen Konstruktors vonnewIncompleteFuturekann jetzt die Kontrolle über dieCompletionStage übernommen werden Instanzen, die in den meisten APIs vonCompletionStagezurückgegeben werden.

Verzögerungen und Zeitüberschreitungen werden definitiv besser unterstützt, wie oben gezeigt. Die hinzugefügten Dienstprogrammmethoden folgen einem sinnvollen Muster und gebenCompletableFuture eine bequeme Möglichkeit, aufgelöste Instanzen anzugeben.

Die in diesem Artikel verwendeten Beispiele finden Sie in unserenGitHub repository.