Подтвердить что ты не робот

Почему ScheduledThreadPoolExecutor принимает только фиксированное количество потоков?

Я могу представить, что некоторые задачи запланированы на очень длительное время, а ScheduledThreadPoolExecutor создаст дополнительные потоки для других задач, которые необходимо запустить, до тех пор, пока не будет достигнуто максимальное количество потоков.

Но кажется, что я могу указать только фиксированное количество потоков для пула, почему это так?

4b9b3361

Ответ 1

Как и почему, я тоже не знаю. Но я могу себе представить.

Объем ресурсов компьютера ограничен. Не все ресурсы могут обрабатываться одновременно.

Если несколько процессов одновременно загружают файлы, они будут загружаться медленнее, чем если бы они загружались последовательно (по крайней мере, на жестком диске).

Процессор также имеет ограниченную поддержку одновременной обработки нескольких потоков. В какой-то момент ОС или JVM будут тратить больше времени на переключение потоков, чем потоки тратят на выполнение своего кода.

Это хорошая причина для того, чтобы ScheduledThreadPoolExecutor был спроектирован так, как есть. Вы можете поместить любое количество заданий в очередь, но никогда не выполнялось больше заданий в одно и то же время, чем можно эффективно выполнять. Разумеется, вам нужно сбалансировать это.

Если ваши задачи привязаны к IO, я бы установил размер пула небольшим, и если они связаны с ЦП, бит больше (32 или около того). Вы также можете сделать несколько ScheduledThreadPoolExecutor s, один для задач с привязкой IO и один для задач с привязкой к ЦП.

Ответ 2

В то время как еще больше проскакивает SchecduledThreadPoolExecutor, я нашел эту ссылку . Эта ссылка объясняет, что SchecduledThreadPoolExecutor решает многие проблемы класса Timer. А также причиной введения SchecduledThreadPoolExecutor было замену таймера (из-за различных проблем с таймером). Я думаю, что причина для фиксированного количества потоков, переданных SchecduledThreadPoolExecutor, является одной из проблем, решаемых этим классом. т.е.

Класс Timer запускает только один нить. Хотя он более эффективен чем создание потока для каждой задачи, это не оптимальное решение. Оптимальный решение может заключаться в использовании ряда потоки между одним потоком для всех задач и одного потока на одну задачу. В эффект, лучшим решением является размещение задачи в пуле потоков. количество потоков в пуле должно быть назначенным во время строительства разрешить программе определять оптимальное количество потоков в пуле.

Так что, по-моему, здесь используется прецедент для SchecduledThreadPoolExecutor. В вашем случае вы должны иметь возможность определять оптимальное значение в зависимости от задач, которые вы планируете планировать, и времени, которое эти задачи должны выполнить. Если у меня есть 4 длительных задания, которые запланированы на одно и то же время, я бы предпочел, чтобы размер моего пула был больше 4, если в то же время выполняются другие задачи. Я также предпочел бы отделить длительные задачи в разных исполнителях, как указано в более ранних ответах.

Надеюсь, что это поможет:)

Ответ 3

Согласно Java Concurrency на практике, существуют следующие недостатки создания неограниченных потоков:

Поток жизни жизненного цикла

Создание темы и удаление не являются бесплатными. Создание потока занимает много времени и требует некоторой обработки JVM и ОС.

Потребление ресурсов

Активные потоки потребляют системные ресурсы, особенно память. Если потоков больше, чем доступных процессоров, потоки работают без дела. Наличие большого количества незанятых потоков может связать много памяти, оказать давление на сборщик мусора, а наличие множества потоков, конкурирующих за ЦП, также может привести к другим затратам на производительность. Если у вас достаточно потоков, чтобы все процессоры были заняты, создание дополнительных потоков не поможет, а может даже повредит.

стабильность

Существует ограничение на количество создаваемых потоков. Ограничение зависит от платформы и зависит от таких факторов, как параметры вызова JVM, запрошенный размер стека в конструкторе Thread и ограничения на потоки, размещенные базовой операционной системой. Когда вы достигнете предела htis, наиболее вероятным результатом будет OutOfMemoryError. Попытка восстановиться после такой ошибки очень рискованна; гораздо проще структурировать вашу программу, чтобы не превышать этот предел.


До определенного момента, большее количество потоков может улучшить пропускную способность, но после этого создание большего количества потоков просто замедляет работу вашего приложения, а создание слишком большого количества потоков может привести к ужасному сбою всего приложения. Чтобы избежать опасности, нужно ограничить количество потоков, создаваемых вашим приложением, и тщательно протестировать ваше приложение, чтобы гарантировать, что даже при достижении этого предела ресурсы не будут исчерпаны.

Может показаться, что создание неограниченных потоков прекрасно работает во время создания прототипов и разработки, а проблемы возникают только при развертывании приложения и при большой нагрузке.