2016-09-13 2 views
12

Um einige Sachen parallel zu laufen oder Asynchron i entweder eine ExecutorService verwenden können: <T> Future<T> submit(Runnable task, T result); oder CompletableFuture Api: static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor); (Lets i in beiden Fällen verwenden die übernehmen gleicher Executor)ExecutorService.submit (Aufgabe) vs CompletableFuture.supplyAsync (Aufgabe, Executor)

Neben dem Rückgabetyp Future vs. CompleableFuture gibt es bemerkenswerte Unterschiede. Oder Wann soll was genutzt werden?

Und was sind die Unterschiede, wenn ich die CompletableFutureApi mit Standard Executor (die Methode ohne Executor) verwenden?

+0

'CompletableFuture' ist neuer und hat viel mehr Fähigkeiten mit einer überlegenen API. Ich empfehle es wann immer möglich zu verwenden. 'Future' ist beklagenswert. –

+0

Gibt es Fakten? Ich möchte Code nicht refaktorieren, weil eine API nur "neuer" imho ist, könnte es Executorservices geben, die CompetableFuture zurückgeben. – dermoritz

+2

Das grundlegende Problem mit 'Future' ist, dass Sie Threads verschwenden müssen, die auf ihre Fertigstellung warten. 'CompletableFuture' dreht das Skript um und ruft in der Zukunft Callbacks auf, wenn es fertig ist. Sie müssen keinen Thread bei 'get()' blockieren. –

Antwort

10

Neben dem Rückgabetyp Future vs. CompleableFuture gibt es bemerkenswerte Unterschiede. Oder Wann soll was genutzt werden?

Es ist wirklich ziemlich einfach. Sie verwenden die Future, wenn Sie möchten, dass der ausführende Thread auf asynchrone Berechnungsantwort wartet. Ein Beispiel dafür ist eine parallele Zusammenführung/Sortierung. Sortiere asynchron links, sortiere synchron, warte nach links, um abzuschließen (future.get()), füge Ergebnisse zusammen.

Sie verwenden eine CompleteableFuture, wenn Sie möchten, dass eine Aktion mit dem Ergebnis nach Abschluss asynchron vom ausgeführten Thread ausgeführt wird. Zum Beispiel: Ich möchte einige Berechnungen asynchron durchführen und die Ergebnisse bei der Berechnung in ein System schreiben. Der anfordernde Thread muss dann möglicherweise nicht auf ein Ergebnis warten.

Sie können das obige Beispiel in einer einzigen ausführbaren Future-Datei nachahmen, aber die CompletableFuture bietet eine flüssigere Schnittstelle mit besserer Fehlerbehandlung.

Es hängt wirklich davon ab, was Sie tun möchten.

Und was sind die Unterschiede, wenn ich die CompletableFutureApi mit Standard Executor (die Methode ohne Executor) verwenden?

Es wird an ForkJoin.commonPool() delegieren, die eine Standardgröße zu der Anzahl der CPUs auf Ihrem System ist. Wenn Sie etwas IO-intensives (Lesen und Schreiben in das Dateisystem) tun, sollten Sie den Thread-Pool anders definieren.

Wenn es CPU-intensiv ist, macht die Verwendung des commonPool am meisten Sinn.

+0

danke. Also, wenn ich die Antwort nicht brauche (im Falle von runnable) oder ich brauche nicht die Funktionen von CompletableFuture, gibt es keinen Unterschied? Könnten Sie kurz ein Beispiel nennen, was der Hauptvorteil ist? – dermoritz

+1

Diese Antwort macht nicht deutlich, warum Sie 'Future' jemals wollen. Der Vorteil von 'CompletableFuture' (asynchrone Auslösung von Folgeaktionen) ist einzigartig, aber es gibt keinen Vorteil für' Future' - das "Warten auf Ergebnis" gilt gleichermaßen für 'CompleableFuture'. – BeeOnRope

1

CompletableFuture reiche Funktionen wie Verkettungs mehr Futures hat, die Futures-Kombination, die Ausführung eine Aktion nach der Zukunft ausgeführt wird (sowohl synchron als auch asynchron) usw.

ist jedoch CompletableFuture nicht anders als Zukunft in Bezug auf Performance. Selbst wenn mehrere Instanzen von CompletableFuture kombiniert werden (mit .thenCombine und .join am Ende), wird keine davon ausgeführt, es sei denn, wir rufen die Methode .get auf und während dieser Zeit wird der aufrufende Thread blockiert. Ich fühle mich in Sachen Leistung nicht besser als Future.

Bitte lassen Sie mich wissen, wenn mir hier ein Aspekt der Leistung fehlt.

Verwandte Themen