Нить против Завершающего 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.