У меня есть следующая функция, в псевдокоде:Рекурсивный параллелизм
Result calc(Data data) {
if (data.isFinal()) {
return new Result(data); // This is the actual lengthy calculation
} else {
List<Result> results = new ArrayList<Result>();
for (int i=0; i<data.numOfSubTasks(); ++i) {
results.add(calc(data.subTask(i));
}
return new Result(results); // merge all results in to a single result
}
}
Я хочу, чтобы распараллелить его, используя фиксированное количество потоков.
Моя первая попытка была:
ExecutorService executorService = Executors.newFixedThreadPool(numOfThreads);
Result calc(Data data) {
if (data.isFinal()) {
return new Result(data); // This is the actual lengthy calculation
} else {
List<Result> results = new ArrayList<Result>();
List<Callable<Void>> callables = new ArrayList<Callable<Void>>();
for (int i=0; i<data.numOfSubTasks(); ++i) {
callables.add(new Callable<Void>() {
public Void call() {
results.add(calc(data.subTask(i));
}
});
}
executorService.invokeAll(callables); // wait for all sub-tasks to complete
return new Result(results); // merge all results in to a single result
}
}
Однако это быстро застрял в тупик, потому что, в то время как верхние ожидания уровня рекурсии для всех потоков, чтобы закончить внутренние уровни и ждать, пока потоки становятся доступными ...
Как я могу эффективно распараллеливать свою программу без взаимоблокировок?
В чем вопрос? –
Мы не видим синхронизации в вашем коде, поэтому мы не можем помочь вам найти тупик. Предоставленный код не имеет ничего общего с взаимоблокировками. – ATrubka
Возможно, это просто, что numOfThreads меньше, чем callables.size()? Вы должны убедиться в своей реализации, что у вас больше потоков, чем вызывающих (вниз по дереву). – cybye