Я понимаю, что java parallelStream (или ForkJoinPool) предназначен для максимального использования ЦП. Из-за отличного сочетания функциональных интерфейсов потока Java (таких как карта, уменьшение, фильтр) и ForkJoinPool я использую параллельный поток Java и ForkJoinPool.
Проблема в том, что ForkJoin не ограничивает количество активных потоков. Если некоторые потоки заблокированы, пока они занимают большой объем памяти, ForkJoinPool пытается создать больше потоков, чтобы обеспечить параллелизм (работающий поток).
В этом случае использование процессора будет максимальным, но память кучи будет исчерпана или даже перейдет в состояние OOM.
Как я могу ограничить количество активных потоков ForkJoinPool?
Или есть альтернативы интерфейсу потока Java?
Я понимаю, что java parallelStream (или ForkJoinPool) предназначен для максимального использования ЦП.
Это не совсем цель. Это может иметь эффект максимального использования ЦП, но цель состоит в том, чтобы ускорить вычисления. Это НЕ одно и то же.
Как я могу ограничить количество активных потоков ForkJoinPool?
Согласно этой ветке списка рассылки , один из способов предотвратить взрыв пула потоков forkjoin в патологических ситуациях — предоставить пользовательский ForkJoinThreadFactory
, который отслеживает количество существующих потоков (каким-то образом) и возвращает null
, когда уже существует слишком много потоков.
Имейте в виду, что если вы достигнете предела (установленного вашей фабрикой), вы получите RejectedExecutionException
s за отправку задачи.
Или есть альтернативы интерфейсу потока Java?
Я не знаю ни одного.
Но я не уверен, что вы вообще столкнетесь с этой проблемой при обычном использовании Stream.parallelStream()
.
Если вы столкнулись с этим и отказы в выполнении вызывают проблемы, вам, вероятно, придется поискать другой способ выражения вычислений; например используя сопрограммы, а не потоки, или с рабочими очередями и Executor
, или что-то еще, о чем я не подумал :-)