ForkJoinTask против CompletableFuture

В Java 8 есть два способа запуска асинхронных вычислений — CompletableFuture и ForkJoinTask. Они оба кажутся довольно похожими — внутренние классы CompletableFuture даже расширяют ForkJoinTask.

Есть ли причина использовать один над другим?

Одно ключевое отличие, которое я вижу, заключается в том, что метод CompletableFuture.join просто блокируется до тех пор, пока будущее не будет завершено (waitingGet просто вращается с использованием ManagedBlocker), тогда как ForkJoinTask.join может украсть работу из очереди, чтобы помочь выполнить задачу, к которой вы присоединяетесь.

Есть ли преимущество перед тем или иным?


person thecoop    schedule 26.11.2015    source источник


Ответы (2)


Это две разные вещи, ForkJoinTask — это задача, которую можно передать ForkJoinPool, CompletableFuture — это промис, который может работать с любым Executor, и исполнителем не обязательно должен быть ForkJoinPool,

Однако верно то, что общий ForkJoinPool используется по умолчанию, если вы его не укажете, например:

CompletableFuture.supplyAsync(()-> supplier);

использует ForkJoinPool, если вы не проходите Executor. Есть еще один overload, который занимает Executor.

CompletableFuture.supplyAsync(()-> supplier,executor);

Async, который является классом static в CompletableFuture, расширяет ForkJoinTask<Void>, но не обязательно должен быть ForkJoinTask, из документов Async

/** Базовый класс может действовать как FJ или обычный Runnable */

abstract static class Async extends ForkJoinTask<Void>
    implements Runnable, AsynchronousCompletionTask 

Он также может Runnable и AsynchronousCompletionTask

Кстати, классы ForkJoinTask, ForkJoinPool, ForkJoin... были добавлены в 1.7, а не в 1.8.

person Sleiman Jneidi    schedule 26.11.2015
comment
Я полагаю, что мой вопрос больше о том, когда вы будете использовать один, а не другой (при условии, что вы используете общий FJP по умолчанию). Присоединение к CompletableFuture помогает выполнить задачу, к которой вы присоединяетесь? - person thecoop; 27.11.2015
comment
@thecoop Я не понимаю, как вы можете заменить одно другим, CompletableFuture — это обещание, которое имеет такие операции, как thenApply и thenCompose, теперь, если у вас вопрос, когда мне использовать ForkJoinTask? Я бы сказал, когда вы пишете свои собственные параллельные алгоритмы - person Sleiman Jneidi; 27.11.2015

Я бы сказал, что ForkJoinTask более рекомендуется, когда у вас есть большая задача и вы хотите разделить ее для параллельного выполнения в нескольких подзадачах. Фреймворк ForkJoin использует алгоритм кражи работы, который эффективно использует потоки. С другой стороны, CompletableFutures больше подходят для модели реактивного программирования, где вы можете создавать конвейеры выполнения в синхронном или асинхронном режиме и лучше контролировать потоки, используя пулы потоков службы исполнителя.

person Alex Guerreiro    schedule 28.09.2016