🛠️ ThreadPoolExecutor saturated, а CPU ещё не 100%?

Это возможно: threads могут ждать database, HTTP, filesystem, locks или другой blocking dependency.

Для execute() логика такая:

threads < corePoolSize → новый thread core достигнут → сначала queue queue не принимает → threads растут до maximumPoolSize queue не принимает + pool at max → RejectedExecutionHandler

Отсюда важная ловушка.

corePoolSize = 10 maximumPoolSize = 100 queue = new LinkedBlockingQueue<>()

Без заданной capacity такая queue практически неограниченная.

После загрузки core threads задачи будут накапливаться в queue, а pool обычно не вырастет до 100.

Поэтому увеличение maximumPoolSize может ничего не изменить.

С bounded queue executor после её заполнения может расти выше core — до max.

Но bounded queue сама по себе overload не решает: нужна понятная rejection/backpressure strategy.

RejectedExecutionException тоже не обязательна.

Её бросает AbortPolicy; другая policy может вести себя иначе.

Перед tuning соберите:

— core/max pool size; — poolSize и approximate activeCount; — тип и capacity queue; — incoming и completed rate; — task latency; — rejection policy; — downstream latency.

Главный вопрос:

это временный burst или incoming rate стабильно выше completion rate?

Во втором случае большая queue только откладывает проблему.

Сохраните параметры, которые нужно собрать до изменения размера thread pool.

😄VK | 💬Макс | 🌐 Cайт 🔹🔹🔹🔹

🛠️ ThreadPoolExecutor saturated, а CPU ещё не 100%?
Это возможно: threads могут ждать database, HTTP, filesystem, locks или другой blocking dependency | Сетка — социальная сеть от hh.ru