2016-03-27 7 views
-3

技術的には同じコードスニペットを2つ持っていますが、2つ目は1秒後に最初のスニペットをとります。最初のものは、(上記のいずれか6Sを取り、次に第二のコードが一貫1S以上を要する理由7S Here is the link to codeCompletableFutureに時間がかかります - Java 8

CompletableFuture<Double> earlyEarningsInHomeCountryCF = currencyConvCF.thenApplyAsync(currencyConv -> { 
     Double yearlyEarnings = employmentService.getYearlyEarningForUserWithEmployer(userId, emp.getId()); 
     return currencyConv * yearlyEarnings; 
}); 

が教えてくださいとる6秒で実行し、7

Double yearlyEarnings = employmentService.getYearlyEarningForUserWithEmployer(userId, emp.getId()); 

CompletableFuture<Double> earlyEarningsInHomeCountryCF = currencyConvCF.thenApplyAsync(currencyConv -> { 
    return currencyConv * yearlyEarnings; 
}); 

第二以下は、最初の

に比べて余分な時間が)メソッドの署名であるgetYearlyEarningForUserWithEmployer。ただ、共有するが、それは任意の

Double getYearlyEarningForUserWithEmployer(long userId, long employerId); 

Here is the link to code

+0

employService.getYearlyEarningForUserWithEmployer()のスニペットを与えることができます – Naruto

+0

どのように違いがありますか? – Robin

+0

[mcve]を作成してください。 – Tunaki

答えて

0

。私はその質問が最良の方法で書かれていないことに同意する。

問題は、先物が書かれた順序が時間の一貫した増加を引き起こしていたことでした。

理想的には、将来のためには、限り、コードが正しい反応性形で書かれているような問題の理由は、JavaのデフォルトForkJoinPoolだった

問題ではないはずとJavaは、すべて実行するために、デフォルトではこのプールを使用していますCompletableFutures。カスタムプールですべてのCompletableFutuesを実行すると、将来のステートメントが書き込まれた順序に関係なく、ほぼ同じ時間になります。

私はまだForkJoinPoolの制限事項を見つけて、20スレッドのカスタムプールがうまく動作するかどうかを調べる必要があります。

正しい理由がわかったら、私の答えを更新します。

0

に影響を与えてはならないあなたの質問は恐ろしく不完全であるが、私たちはcurrencyConvCFと仮定した場合、我々は推測することができるものから、それは、第二の変形に時間がかかることを完全にもっともらしいですコードフラグメントが実行されている間に同時に実行されている可能性があり、thenApplyAsyncearlyEarningsInHomeCountryCF)によって返されたCompletableFutureによって表されるものを含む、すべての操作を完了するのにかかる全体的な時間について話している非同期操作を表します。

最初の変形ではを呼び出していますが、currencyConvCFで表される操作は同時に実行されている可能性があります。両方の操作が完了すると、乗算が行われます。第二の変形例において

getYearlyEarningForUserWithEmployer呼び出しはcurrencyConvCFで表される動作が完了する前に、このようにして、それが起動しないので、何も操作が同時に実行されません、currencyConvCF.thenApplyAsyncに渡された操作の一部です。 getYearlyEarningForUserWithEmployerがかなりの時間(例えば1秒)を要し、他の操作に内部的な依存性がないと仮定すると、その操作で全体の操作に時間がかかることは驚くことではありません。

CompletableFuture<Double> earlyEarningsInHomeCountryCF = currencyConvCF.thenCombineAsync(
    CompletableFuture.supplyAsync(
     () -> employmentService.getYearlyEarningForUserWithEmployer(userId, emp.getId())), 
    (currencyConv, yearlyEarnings) -> currencyConv * yearlyEarnings); 

のでgetYearlyEarningForUserWithEmployerが実行されず、開始スレッドで逐次が、最終的な乗算が適用される前に、両方のソース操作を非同期で実行することができます:あなたが実際に何をしたいのか

それはそうでは、のようなものです。

しかし、最初のスレッドでgetを呼び出すと、githubのリンクコードのように、2番目の操作の非同期処理には効果がありません。完了を待つ代わりに、あなたの開始スレッドは、あなたの質問の第2のコード変種がすでに行っているように独立した操作を実行するだけで、非同期操作を単一の乗算、代わりに:ホルガーは私が掲示問題で意味を作るのではなく、言った今までに何

CompletableFuture<Double> currencyConvCF = /* a true asynchronous operation */ 
return employmentService.getYearlyEarningForUserWithEmployer(userId, emp.getId()) 
    * employerCurrencyCF.join(); 
関連する問題