Я пытаюсь использовать ForkJoinPool для распараллеливания вычислений с интенсивным вычислением процессора. Мое понимание ForkJoinPool заключается в том, что он продолжает работать до тех пор, пока любая задача доступна для выполнения. К сожалению, я часто наблюдал за рабочими потоками на холостом ходу/ожидании, поэтому не все CPU остаются занятыми. Иногда я даже наблюдал дополнительные рабочие потоки.ForkJoinPool stalls во время invokeAll/join
Я этого не ожидал, так как я строго старался использовать non blocking задач. Мое наблюдение очень похоже на наблюдение ForkJoinPool seems to waste a thread. После отладки в ForkJoinPool у меня есть предположение:
Я использовал invokeAll() для распространения работы над списком подзадач. После того, как invokeAll() закончил выполнение первой задачи, он начинает соединяться с другими. Это отлично работает, пока следующая задача для присоединения не находится поверх очереди выполнения. К сожалению, я выполнил дополнительные задачи асинхронно, не присоединившись к ним. Я ожидал, что ForkJoin Framework продолжит выполнение этой задачи сначала, а затем вернется к объединению любых оставшихся задач.
Но, похоже, это не работает. Вместо этого рабочий поток блокируется вызовом wait(), пока задача, ожидающая получения, не будет готова (предположительно, выполнена другим рабочим потоком). Я не проверял это, но, похоже, это общий недостаток вызова join().
ForkJoinPool предоставляет asyncMode, но это глобальный параметр и не может использоваться для отдельных представлений. Но мне нравится, когда мои асинхронно разветвленные задачи будут выполнены в ближайшее время.
Итак, почему ForkJoinTask.doJoin() не просто выполняет любую доступную задачу поверх своей очереди, пока она не будет готова (либо выполнена сама по себе, либо украдена другими)?
Вы можете поделиться с нами своим кодом? Когда-то 3 строки кода говорят более 30 строк прозы. – Fildor
Я положил что-то здесь: http://pastebin.com/kgHuJZMM – Ditz