ExecutorService: рекурсивный обход дерева и параллельное вычисление некоторых результатов на каждом узле - PullRequest
0 голосов
/ 29 сентября 2019

Вот пара примеров кодов из книги «Параллелизм 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 не обязательно будет таким же, как порядок обходаузлов в дереве и зависит главным образом от того, сколько времени потребуется для вычисления результатов для конкретного узла, который может варьироваться от узла к узлу?

...