Часто задаю данный вопрос на интервью джавистам, и 9 из 10 отвечают примерно так:
Размер пула задаем по количеству ядер процессора, а задавать больше смысла не имеет, так как все ядра будут заняты
Так это или нет - давайте разбираться.
Для наглядности запишем утверждение приведенное выше в виде формулы:
Теперь давайте поразмышляем, какими вообще могут быть задачи, которые будут запускаться в нашем пуле:
- могут содержать большое количество вычислений;
- могут содержать большое количество задержек (например ожидание ввод-вывода);
- по времени могут быть быстрыми или длительными.
Глядя на Формулу №1 видим, что данные особенности никак не учтены, и имея задачи с большим числом задержек и большой длительностью, получим, что все потоки пула будут заняты ожиданием, а утилизация процессора около нулевая.
Давайте рассмотрим другую формулу, в которой уже учитываются время ожидания и время вычислений:
Рассмотрим Формулу №2 на примерах:
Пример 1:
countCpu = 8
Twait = 750ms
Tcalc = 250ms
poolSize = 16 * ((750/250)+1) = 64
Пример 2:
countCpu = 8
Twait = 0ms
Tcalc = 500ms
poolSize = 16 * ((0/250)+1) = 16
Из Примера 2 видим, что Формула №1 является частным случаем Формулы №2, если в задачах нет задержек/ожидания.
Делаем вывод:
- чем выше процент времени ожидания, тем больше потоков требуется
- чем выше процент времени вычислений, тем меньше требуется потоков.
Кроме того, справедливо стоит заметить, что Twait и Tcalc - это не константные значения, и вычислять/подбирать их придется статистически, используя бенчмарки или метрики.
Также встречается, что в Формулу №2 иногда добавляю еще один множитеть loadCpu - коэффициент/процент загруки процессора
Коэффициент loadCpu помогает нам исключить из расчета % cpu, который потребляют, например, система и другие приложения.
Источники:
https://russianblogs.com/article/4806403300/
https://russianblogs.com/article/6474290748/
Также подписывайтесь на
мой telegram: https://t.me/onakrainikoff
мой github https://github.com/onakrainikoff
#java #threadpool #threadpoolsize