Насколько я понимаю, ForkJoinPool использует «принцип« первым пришел - первым вышел »(LiFo)». Возможно, лучшее объяснение, которое я смог найти, это эта ссылка . Однако метод invokeall()
в ForkJoinPool. java, кажется, присоединяется (quietlyjoin ()?) К задачам в порядке их отправки (FiFo), см. Код ниже. Разве не имеет смысла делать это наоборот, поскольку вся обработка - это LiFo?
Не приведет ли это к уменьшению количества «компенсационных потоков»? Я думаю переписать свой код для отправки задач, а не использовать invokeall()
, и из-за этого присоединиться к ним на основе LiFo. См. Также:
ForkJoinPool останавливается во время invokeAll / join
Кажется, что ForkJoinPool теряет поток
РЕДАКТИРОВАТЬ : есть разница, передается ли задача во внешнюю очередь или в очередь рабочего. Я ссылаюсь на рабочую палубу. Я предполагаю, что invokeall () может привести к установке потоков здесь.
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) {
// In previous versions of this class, this method constructed
// a task to run ForkJoinTask.invokeAll, but now external
// invocation of multiple tasks is at least as efficient.
ArrayList<Future<T>> futures = new ArrayList<>(tasks.size());
try {
for (Callable<T> t : tasks) {
ForkJoinTask<T> f = new ForkJoinTask.AdaptedCallable<T>(t);
futures.add(f);
externalSubmit(f);
}
for (int i = 0, size = futures.size(); i < size; i++)
((ForkJoinTask<?>)futures.get(i)).quietlyJoin();
return futures;
} catch (Throwable t) {
for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).cancel(false);
throw t;
}
}