В чем преимущества использования новой структуры 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 "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?