web-dev-qa-db-ja.com

スレッドとCompletableFuture

代わりにCompletableFutureを使用するのではなく、スレッドにコードを直接渡す利点は何ですか?

Thread thread = new Thread(() -> {do something});
thread.start();

VS

CompletableFuture<Void> cf1 =  
     CompletableFuture.runAsync(() -> {do something}); 
15
Sagar

CompletableFuture.runAsync(...)は、RunnableをforkJoin-Poolで実行します管理されている = new Thread()は、新しいスレッドを作成します管理する必要がある

"管理されている"の意味は、事前に割り当てられており、スレッドはJVMで共有されています。ランナブルが完了すると、スレッドは他のランナブルに再利用できます。これにより、特にスレッドのインスタンス化はオブジェクトだけでなく、追加の非ヒープメモリ(スレッドスタック)も割り当てる必要があるため、負荷の高い操作であるため、リソースの使用率が向上します。

14
Gerald Mücke

@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を使用すると、深刻な問題が簡単に発生します。

3
Hearen