Когда указывать отдельные размеры ядра и максимального пула в ThreadPoolExecutor - хорошая идея?

Я пытаюсь понять смысл указания отдельных размеров ядра и максимального пула для ThreadPoolExecutor Java 5. Насколько я понимаю, количество потоков увеличивается только после заполнения очереди, что кажется немного запоздалым (по крайней мере, с большими очередями).

Разве я не счастлив выделить для задач большее количество потоков, и в этом случае я мог бы просто увеличить размер основного пула; или я не очень хочу этого делать, и в таком случае мне лучше иметь очередь побольше? В каком сценарии полезны отдельные размеры ядра и максимального пула?


person Peter Becker    schedule 20.09.2011    source источник


Ответы (2)


Обсуждение этого находится здесь.

Пул предназначен для работы при нормальной нагрузке на уровне corePoolSize (до которого он увеличивается, если не используется предварительный запуск). Когда возникает состояние перегрузки (определяется тем, что ожидающих / находящихся в процессе задач больше, чем рабочих), мы используем очередь в качестве буфера - с ожиданием, что нормальная рабочая нагрузка будет восстановлена ​​в ближайшем будущем. Если нас беспокоит чрезмерная перегрузка, мы можем использовать ограниченную очередь, в которой говорится: «Если очередь заполняется, добавьте больше рабочих процессов до maxPoolSize». Если мы используем неограниченную очередь, мы говорим, что не ожидаем (или не заботимся о) чрезмерной перегрузки.

Цель состоит в том, чтобы сбалансировать способность обрабатывать ожидаемую рабочую нагрузку, даже при переходных перегрузках, без чрезмерного создания потоков и без слишком большого оттока потоков (например, create-work-die-create).

person sbridges    schedule 21.09.2011
comment
Это отличное объяснение! Поправил мертвую ссылку. Обсуждение, указанное в ответе, можно найти на странице comments.gmane .org / gmane.comp.java.jsr.166-concurrency / 7109 - person Shailendra; 11.04.2015

Разница в том, что если ваш размер меньше основного пула, каждая новая задача создает новый поток независимо от незанятых потоков в пуле. Количество потоков увеличивается только после заполнения очереди, когда вы уже достигли размера основного пула, но все еще ниже максимума.

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

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

person Bringer128    schedule 21.09.2011
comment
Но тогда я мог бы начать с большего количества потоков - иначе я просто добавляю задержку задачам, ожидающим в очереди. Я также подозреваю, что во многих сценариях, в которых очередь заполняется, она может заполняться быстро, и в этом случае дополнительные потоки могут появиться слишком поздно. - person Peter Becker; 21.09.2011
comment
@Peter, если ваш статический анализ достаточно хорош, чтобы предсказать правильное количество потоков для использования при чрезмерной нагрузке, и вы довольны тем, что эти дополнительные потоки сидят без дела во время нормальной нагрузки, тогда действуйте! Это компромисс между однократным временем раскрутки потока под нагрузкой или использованием дополнительных ресурсов при низкой нагрузке. - person Bringer128; 21.09.2011