Вот пара примеров кодов из книги «Параллелизм Java на практике» (листинги 8.11 и 8.12, глава 8.5 «Распараллеливание рекурсивных алгоритмов» ).Он иллюстрирует обход дерева в глубину, выполняя вычисления для каждого узла и помещая результат в коллекцию.
public<T> void parallelRecursive(final Executor exec,
List<Node<T>> nodes,
final Collection<T> results) {
for (final Node<T> n : nodes) {
exec.execute(new Runnable() {
public void run() {
results.add(n.compute());
}
});
parallelRecursive(exec, n.getChildren(), results);
}
}
Затем вызывающие parallelRecursive()
могут ожидать всех результатов, используя shutdown()
и awaitTermination()
, как показано здесь:
public<T> Collection<T> getParallelResults(List<Node<T>> nodes)
throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
Queue<T> resultQueue = new ConcurrentLinkedQueue<T>();
parallelRecursive(exec, nodes, resultQueue);
exec.shutdown();
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
return resultQueue;
}
И это мой вопрос: правильно ли говорить, что порядок вычислений, в результате которого resultQueue
не обязательно будет таким же, как порядок обходаузлов в дереве и зависит главным образом от того, сколько времени потребуется для вычисления результатов для конкретного узла, который может варьироваться от узла к узлу?