代わりにCompletableFutureを使用するのではなく、スレッドにコードを直接渡す利点は何ですか?
Thread thread = new Thread(() -> {do something});
thread.start();
VS
CompletableFuture<Void> cf1 =
CompletableFuture.runAsync(() -> {do something});
CompletableFuture.runAsync(...)
は、RunnableをforkJoin-Poolで実行します管理されている = new Thread()
は、新しいスレッドを作成します管理する必要がある 。
"管理されている"の意味は、事前に割り当てられており、スレッドはJVMで共有されています。ランナブルが完了すると、スレッドは他のランナブルに再利用できます。これにより、特にスレッドのインスタンス化はオブジェクトだけでなく、追加の非ヒープメモリ(スレッドスタック)も割り当てる必要があるため、負荷の高い操作であるため、リソースの使用率が向上します。
@GeraldMückeはすでに重要な違いについて述べました:
CompletableFuture.runAsync(...)は、管理されているforkJoin-PoolでRunnableを実行しますが、new Thread()は、管理する必要がある新しいスレッドを作成します。
CompletableFutureは、ThreadPool(デフォルトまたはカスタマイズ)によって管理されるスレッドを使用します。
ただし、次の2点も考慮すべきだと思います。
CompletableFutureには簡単に理解できるメソッドからchainまでのさまざまな非同期計算を組み合わせることで、Threadを直接使用するよりもはるかに簡単に非同期を導入できます。
CompletableFuture[] futures = IntStream.rangeClosed(0, LEN).boxed()
.map(i -> CompletableFuture.supplyAsync(() -> runStage1(i), EXECUTOR_SERVICE))
.map(future -> future.thenCompose(i -> CompletableFuture.supplyAsync(() -> runStage2(i), EXECUTOR_SERVICE)))
.toArray(size -> new CompletableFuture[size]);
CompletableFuture.allOf(futures).join();
exceptions;の処理を忘れないでください。 CompletableFutureでは、次のように直接処理できます。
completableFuture.handle((s, e) -> e.toString()).join()
または、この方法を利用して計算を中断します。
completableFuture.completeExceptionally(new RuntimeException("Calculation failed!"));
Threadを使用すると、深刻な問題が簡単に発生します。