Нить против Завершающего Future

В чем преимущество передачи кода непосредственно в поток vs с использованием CompletableFuture?

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

В.С.

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

Ответ 1

CompletableFuture.runAsync(...) запускает Runnable в управляемом forkJoin-пуле, а new Thread() создает новый поток, который вам нужно управлять.

То, что "управляется", означает, что оно предварительно выделено, а потоки разделяются в JVM. Когда runnable завершен, поток может быть повторно использован для других runnables. Это улучшает использование ресурсов, особенно в том случае, если потоковая реализация - дорогостоящая операция - должен быть выделен не только объект, но и некоторая дополнительная память без кучи - стек потока.

Ответ 2

@Gerald Mücke уже упомянул важное различие:

CompletableFuture.runAsync(...) запускает Runnable в управляемом forkJoin-Pool, в то время как new Thread() создает новый поток, которым вы должны управлять.

CompletableFuture будет использовать потоки, управляемые ThreadPool (по умолчанию или настраиваемые).

Тем не менее, я думаю, что следующие два пункта также должны быть рассмотрены.

Первый

CompletableFuture так много легко понятных методов для цепных различных асинхронных вычислений вместе, что делает его гораздо легче ввести асинхронность, чем непосредственно с помощью 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();

второй

Вы никогда не должны забывать обрабатывать исключения; с CompletableFuture вы можете напрямую обрабатывать их следующим образом:

completableFuture.handle((s, e) -> e.toString()).join()

или воспользуйтесь этим способом, чтобы прервать вычисление:

completableFuture.completeExceptionally(new RuntimeException("Calculation failed!"));

в то время как вы легко столкнетесь с некоторыми серьезными проблемами при использовании Thread.