Каковы преимущества использования новой платформы fork / join по сравнению с простым разбиением большой задачи на N подзадач в начале, отправкой их в пул кэшированных потоков (из Executors ) и ждете завершения каждого задания? Я не вижу, как использование абстракции fork / join упрощает проблему или делает решение более эффективным по сравнению с тем, что было у нас годами.
Например, алгоритм распараллеленного размытия в учебном примере может быть реализован так:
public class Blur implements Runnable {
private int[] mSource;
private int mStart;
private int mLength;
private int[] mDestination;
private int mBlurWidth = 15; // Processing window size, should be odd.
public ForkBlur(int[] src, int start, int length, int[] dst) {
mSource = src;
mStart = start;
mLength = length;
mDestination = dst;
}
public void run() {
computeDirectly();
}
protected void computeDirectly() {
// As in the example, omitted for brevity
}
}
Разделить в начале и отправить задачи в пул потоков:
// source image pixels are in src
// destination image pixels are in dst
// threadPool is a (cached) thread pool
int maxSize = 100000; // analogous to F-J's "sThreshold"
List<Future> futures = new ArrayList<Future>();
// Send stuff to thread pool:
for (int i = 0; i < src.length; i+= maxSize) {
int size = Math.min(maxSize, src.length - i);
ForkBlur task = new ForkBlur(src, i, size, dst);
Future f = threadPool.submit(task);
futures.add(f);
}
// Wait for all sent tasks to complete:
for (Future future : futures) {
future.get();
}
// Done!
Задачи попадают в очередь пула потоков, из которой они выполняются по мере доступности рабочих потоков. Пока разделение достаточно гранулировано (чтобы избежать особого ожидания последней задачи) и в пуле потоков достаточно (по крайней мере, N процессоров) потоков, все процессоры работают на полной скорости, пока не будут выполнены все вычисления.
Я что-то упустил? Какова дополнительная ценность использования структуры fork / join?