Ihre Frage schrecklich unvollständig beeinflussen, aber von dem, was wir denken können, ist es durchaus plausibel, dass die zweite Variante länger dauert, wenn wir davon ausgehen, dass currencyConvCF
stellt einen asynchronen Vorgang dar, der möglicherweise gleichzeitig ausgeführt wird, während Ihre Codefragmente ausgeführt werden, und Sie sprechen von der Gesamtzeit, die für die Ausführung aller Vorgänge benötigt wird, einschließlich der von CompletableFuture
zurückgegebenen thenApplyAsync
(earlyEarningsInHomeCountryCF
).
In der ersten Variante rufen Sie getYearlyEarningForUserWithEmployer
auf, während die durch currencyConvCF
dargestellte Operation möglicherweise noch gleichzeitig ausgeführt wird. Die Multiplikation erfolgt, wenn beide Operationen abgeschlossen sind.
In der zweiten Variante wird der getYearlyEarningForUserWithEmployer
Aufruf ist Teil der Operation zu currencyConvCF.thenApplyAsync
vergangen, so wird es nicht gestartet werden, bevor die durch currencyConvCF
dargestellte Operation abgeschlossen war, so wird keine Operation gleichzeitig ausgeführt werden. Wenn wir annehmen, dass getYearlyEarningForUserWithEmployer
eine beträchtliche Zeit braucht, sagen wir eine Sekunde, und keine internen Abhängigkeiten zu der anderen Operation hat, ist es nicht überraschend, wenn die gesamte Operation in dieser Variante länger dauert.
Es scheint, was Sie eigentlich tun wollen so etwas wie:
CompletableFuture<Double> earlyEarningsInHomeCountryCF = currencyConvCF.thenCombineAsync(
CompletableFuture.supplyAsync(
() -> employmentService.getYearlyEarningForUserWithEmployer(userId, emp.getId())),
(currencyConv, yearlyEarnings) -> currencyConv * yearlyEarnings);
so wird getYearlyEarningForUserWithEmployer
in dem initiierenden Thread nicht nacheinander ausgeführt werden aber beide Quellvorgänge können asynchron ausgeführt werden, bevor die endgültige Multiplikation gilt.
Wenn Sie jedoch direkt im initiierenden Thread get
aufrufen, wie in Ihrem verknüpften Code auf GitHub, hat diese asynchrone Verarbeitung der zweiten Operation keinen Vorteil. Anstatt auf die Vervollständigung zu warten, kann Ihr initiierender Thread nur die unabhängige Operation ausführen, wie es die zweite Codevariante Ihrer Frage bereits tut, und Sie werden wahrscheinlich noch schneller sein, wenn Sie keine asynchrone Operation für etwas so Einfaches wie eine einfache Multiplikation erzeugen stattdessen:
CompletableFuture<Double> currencyConvCF = /* a true asynchronous operation */
return employmentService.getYearlyEarningForUserWithEmployer(userId, emp.getId())
* employerCurrencyCF.join();
Können Sie Snippet von employmentService.getYearlyEarningForUserWithEmployer() geben – Naruto
Wie macht es einen Unterschied? – Robin
Bitte machen Sie ein [mcve]. – Tunaki