2017-07-03 2 views
1

Ich versuche, die CompletableFuture Schnittstelle in Java 8. Mein aktueller Code zu verstehen ist:CompletableFuture: nach asynchroner Aufruf, Prozessergebnis in aktuellen Thread

CompletableFuture.supplyAsync(() -> wachtwoordBijwerken(gebruikersnaam, wachtwoord)) 
    .thenAccept(this::saveOrUpdateGebruiker) 
    .exceptionally(e -> 
    { 
     log.error("Fout bij het bijwerken van wachtwoord voor gebruiker: " + gebruikersnaam, e); 
     return null; 
    }); 

ich den Anruf saveOrUpdateGebruiker() erwartet im Hauptthread laufen nachdem der asynchrone Aufruf im neu erstellten Thread abgeschlossen ist. Der Aufruf befindet sich jedoch immer noch in einem anderen Thread, was Probleme in der zugrunde liegenden Hibernate-Implementierung verursacht.

Gibt es eine Möglichkeit, CompletableFuture für einen nicht blockierenden Async-Aufruf zu verwenden und trotzdem das Ergebnis in meinem aktuellen Thread zu verwenden?

Antwort

2

Nicht automatisch nicht. Wenn Operationen ausgeführt werden, wie sie von CompletableFuture mit 10, thenAccept usw. bereitgestellt werden, werden sie alle von einem Thread in dem Threadpool ausgeführt. Dies ermöglicht es Ihnen, "Feuer und Vergessen" -Operationen durchzuführen und die Arbeit im Hauptthread fortzusetzen, wie Sie es für richtig halten.

Wenn Sie die Arbeit in Ihrem aktuellen Thread ausführen möchten, nachdem die CompletableFuture beendet ist, müssen Sie warten und überprüfen Sie den Abschluss mithilfe von isDone() und/oder get() Methoden. Wenn Sie dies tun, gibt es keinen Vorteil der Verwendung von CompletableFuture gegenüber einem normalen Future (z.

+0

also das Ergebnis ist eine blockierende Sync-Aufruf? (wegen der get() -Funktion) – Cloud

+1

Nun, es sei denn, Sie 'isDone()' abfragen. Nur so können Sie den aktuellen Thread ausführen. – Kayaman

1

Sie können die Methode thenAcceptAsync(Runnable, Executor) verwenden, die den Vollstrecker verwendet man in Parameter übergeben den Rückruf auszuführen, die es schließlich gleich sein kann, dass die, die Sie für den Anrufer

Wie das haben, können Sie den Faden steuern/Testamentsvollstrecker für die Ausführung Ihres Callback-Code

Siehe auch verwendet: This related Stackoverflow question

+1

Es gibt jetzt zwei widersprüchliche Antworten hier. Vielleicht solltest du deine Antwort etwas modifizieren, da die Antwort nicht "Ja" ist, die Antwort ist "Nein, du kannst es nicht im ** aktuellen Thread **" ausführen. Ansonsten ist die Antwort gut. – Kayaman

+0

Leider ist das nicht korrekt. Selbst mit Executor-Tricks können Sie nicht erreichen, dass der Code in demselben Thread ausgeführt wird, von dem aus Sie 'supplyAsync' aufgerufen haben. Die zugehörige Frage beschreibt einen Executor, der auf dem aktuellen Thread ausgeführt wird, aber diese Frage bezieht sich auf den aktuellen Thread, einen Thread in einem Pool (der 'supplyAsync' ausführt) und schließlich im aktuellen Thread erneut ausgeführt wird. Wenn der beschriebene Executor angegeben wird, ist es der gepoolte Thread, der ihn ausführt (da es der "aktuelle Thread" an diesem Punkt ist). – Kayaman

1

CompletableFuture Verwendung ist ein Overkill für Ihr Szenario. CompleableFuture ist in seinem Design nicht blockierend und wenn der Job fertig ist, können Sie seine Ergebnisse sammeln, indem Sie die Methode join() oder polling isDone() verwenden und dann den synchronen Vorgang ausführen. Wenn Sie nur einen Prozess haben, der weiterhin Aufgaben an dedizierten ThreadPool sendet, hat CompletableFuture keinen Vorteil als CompletionService oder nur ExecutorService. Ich schrieb einen einfachen Blog über ein Szenario, in dem CompletableFuture eine gute Anpassung im Vergleich zu traditionellen Threadpool: https://medium.com/@zhongzhongzhong/beauty-of-completablefuture-and-where-should-you-use-it-6ac65b7bfbe

Verwandte Themen