Verbeteringen in Java 9 CompletableFuture API

1. Inleiding

Java 9 wordt geleverd met enkele wijzigingen in het CompletableFuture klasse. Dergelijke wijzigingen werden geïntroduceerd als onderdeel van JEP 266 om veelvoorkomende klachten en suggesties te behandelen sinds de introductie ervan in JDK 8, meer specifiek ondersteuning voor vertragingen en time-outs, betere ondersteuning voor subclassificatie en een paar hulpprogramma-methoden.

Qua code wordt de API geleverd met acht nieuwe methoden en vijf nieuwe statische methoden. Om dergelijke toevoegingen mogelijk te maken, zijn ongeveer 1500 van de 2400 regels code gewijzigd (volgens Open JDK).

2. Instance API-toevoegingen

Zoals vermeld, wordt de instantie-API geleverd met acht nieuwe toevoegingen, dit zijn:

  1. Executor defaultExecutor ()
  2. CompletableFuture newIncompleteFuture ()
  3. Toekomstige kopie ()
  4. CompletionStage minimalCompletionStage ()
  5. CompletableFuture completeAsync (leverancier leverancier, uitvoerder uitvoerder)
  6. CompletableFuture completeAsync (leverancier leverancier)
  7. CompletableFuture orTimeout (lange time-out, TimeUnit-eenheid)
  8. CompletableFuture completeOnTimeout (T-waarde, lange time-out, TimeUnit-eenheid)

2.1. Methode defaultExecutor ()

Handtekening: Executor defaultExecutor ()

Retourneert de standaardwaarde Uitvoerder gebruikt voor async-methoden die geen Uitvoerder.

nieuwe CompletableFuture (). defaultExecutor ()

Dit kan worden opgeheven door subklassen die een uitvoerder retourneren die ten minste één onafhankelijke thread biedt.

2.2. Methode newIncompleteFuture ()

Handtekening: CompletableFuture newIncompleteFuture ()

De newIncompleteFuture, ook bekend als de "virtuele constructor", wordt gebruikt om een ​​nieuwe, voltooide toekomstige instantie van hetzelfde type op te halen.

nieuwe CompletableFuture (). newIncompleteFuture ()

Deze methode is vooral handig bij subclassificatie CompletableFuture, voornamelijk omdat het intern wordt gebruikt in bijna alle methoden om een ​​nieuw Voltooiingsfase, waardoor subklassen kunnen bepalen welk subtype door dergelijke methoden wordt geretourneerd.

2.3. Methode kopiëren()

Handtekening: Toekomstige kopie ()

Deze methode retourneert een nieuw CompletableFuture welke:

  • Wanneer dit normaal wordt voltooid, wordt de nieuwe normaal ook voltooid
  • Wanneer dit uitzonderlijk wordt voltooid met uitzondering X, wordt de nieuwe ook uitzonderlijk aangevuld met een CompletionException met X als oorzaak
nieuwe CompletableFuture (). copy ()

Deze methode kan nuttig zijn als een vorm van 'defensief kopiëren', om te voorkomen dat klanten het voltooien, terwijl ze toch afhankelijke acties kunnen regelen voor een specifiek exemplaar van CompletableFuture.

2.4. Methode minimalCompletionStage ()

Handtekening: CompletionStage minimalCompletionStage ()

Deze methode retourneert een nieuw Voltooiingsfase die zich op exact dezelfde manier gedraagt ​​als beschreven door de kopieermethode, maar een dergelijke nieuwe instantie gooit UnsupportedOperationException bij elke poging om de opgeloste waarde op te halen of in te stellen.

nieuwe CompletableFuture (). minimalCompletionStage ()

Een nieuw CompletableFuture met alle beschikbare methoden kunnen worden opgehaald met behulp van de toCompletableFuture methode beschikbaar op de Voltooiingsfase API.

2.5. Methoden completeAsync ()

De completeAsync methode moet worden gebruikt om de CompletableFuture asynchroon met behulp van de waarde gegeven door de Leverancier voorzien.

Handtekeningen:

CompletableFuture completeAsync (leverancier leverancier, uitvoerder uitvoerder) CompletableFuture completeAsync (leverancier leverancier)

Het verschil tussen deze twee overbelaste methoden is het bestaan ​​van het tweede argument, waarbij de Uitvoerder het uitvoeren van de taak kan worden gespecificeerd. Als er geen is opgegeven, wordt de standaarduitvoerder (geretourneerd door de defaultExecutor methode) worden gebruikt.

2.6. Methoden ofTimeout ()

Handtekening: CompletableFuture orTimeout (lange time-out, TimeUnit-eenheid)

nieuwe CompletableFuture (). ofTimeout (1, TimeUnit.SECONDS)

Lost het CompletableFuture uitzonderlijk met TimeoutException, tenzij het is voltooid vóór de opgegeven time-out.

2.7. Methode completeOnTimeout ()

Handtekening: CompletableFuture completeOnTimeout (T-waarde, lange time-out, TimeUnit-eenheid)

nieuwe CompletableFuture (). completeOnTimeout (waarde, 1, TimeUnit.SECONDS)

Voltooit het CompletableFuture normaal gesproken met de opgegeven waarde, tenzij deze is voltooid vóór de opgegeven time-out.

3. Statische API-toevoegingen

Er zijn ook enkele hulpprogramma-methoden toegevoegd. Zij zijn:

  1. Executor delayedExecutor (lange vertraging, TimeUnit unit, Executor executor)
  2. Executor delayedExecutor (lange vertraging, TimeUnit-eenheid)
  3. CompletionStage completeStage (U-waarde)
  4. CompletionStage failedStage (Throwable ex)
  5. CompletableFuture failedFuture (Throwable ex)

3.1. Methoden delayedExecutor

Handtekeningen:

Uitvoerder vertraagd Uitvoerder (lange vertraging, TimeUnit-eenheid, Uitvoerder uitvoerder) Uitvoerder vertraagd Uitvoerder (lange vertraging, Tijdeenheid-eenheid)

Retourneert een nieuw Uitvoerder die een taak voorlegt aan de gegeven basisuitvoerder na de gegeven vertraging (of geen vertraging indien niet-positief). Elke vertraging begint bij het aanroepen van de uitvoermethode van de geretourneerde uitvoerder. Als er geen uitvoerder is opgegeven, is de standaarduitvoerder (ForkJoinPool.commonPool ()) zal gebruikt worden.

3.2. Methoden voltooide fase en misluktStage

Handtekeningen:

 CompletionStage completeStage (U-waarde) CompletionStage failedStage (Throwable ex)

Deze hulpprogramma-methoden worden al opgelost geretourneerd Voltooiingsfase instanties, ofwel normaal aangevuld met een waarde (voltooide fase) of uitzonderlijk ingevuld (misluktStage) met de gegeven uitzondering.

3.3. Methode misluktFuture

Handtekening: CompletableFuture failedFuture (Throwable ex)

De FailedFuture-methode voegt de mogelijkheid toe om een ​​reeds voltooid uitzonderlijk op te geven CompleatebleFuture voorbeeld.

4. Voorbeelden van gebruiksscenario's

In deze sectie zal een aantal voorbeelden laten zien van het gebruik van enkele van de nieuwe API.

4.1. Vertraging

Dit voorbeeld laat zien hoe u de voltooiing van een CompletableFuture met een specifieke waarde met één seconde. Dat kan worden bereikt door de completeAsync methode samen met de delayedExecutor.

CompletableFuture future = nieuwe CompletableFuture (); future.completeAsync (() -> invoer, CompletableFuture.delayedExecutor (1, TimeUnit.SECONDS));

4.2. Compleet met waarde op time-out

Een andere manier om een ​​vertraagd resultaat te bereiken, is door de completeOnTimeout methode. In dit voorbeeld wordt een CompletableFuture dat wordt met een bepaalde invoer opgelost als het na 1 seconde onopgelost blijft.

CompletableFuture future = nieuwe CompletableFuture (); future.completeOnTimeout (invoer, 1, TimeUnit.SECONDS);

4.3. Time-out

Een andere mogelijkheid is een time-out waarmee de toekomst uitzonderlijk wordt opgelost TimeoutException. Als u bijvoorbeeld de CompletableFuture time-out na 1 seconde, aangezien het daarvoor niet is voltooid.

CompletableFuture future = nieuwe CompletableFuture (); future.orTimeout (1, TimeUnit.SECONDS);

5. Conclusie

Kortom, Java 9 wordt geleverd met verschillende toevoegingen aan het CompletableFuture API, het heeft nu betere ondersteuning voor subclassering, dankzij de newIncompleteFuture virtuele constructor, is het mogelijk om de controle over de Voltooiingsfase gevallen geretourneerd in de meeste van de Voltooiingsfase API.

Het heeft absoluut betere ondersteuning voor vertragingen en time-outs, zoals eerder is aangetoond. De toegevoegde utiliteitsmethoden volgen een verstandig patroon: geven CompletableFuture een handige manier om opgeloste instanties op te geven.

De voorbeelden die in dit artikel worden gebruikt, zijn te vinden in onze GitHub-repository.