Поддерживает:
- параметры
corePoolSize,maxPoolSize,keepAliveTime,timeUnit,queueSize,minSpareThreads - несколько очередей задач, по одной на каждый worker
- распределение задач по алгоритму Round Robin
- логирование
- политику перегрузки CallerRuns
- методы
execute,submit,shutdown,shutdownNow
docker compose up --build- Каждый worker обслуживает собственную очередь
ArrayBlockingQueue - При запуске создается
max(corePoolSize, minSpareThreads)потоков, не болееmaxPoolSize - Новые задачи распределяются по очередям циклически через Round Robin
- Если выбранная очередь заполнена, пул делает проход по остальным очередям и ищет свободное место
- Если места нет ни в одной очереди, но лимит
maxPoolSizeеще не достигнут, создается новый worker со своей очередью - Если очереди заполнены и новых worker'ов создавать уже нельзя, срабатывает политика CallerRuns
- Если число свободных потоков падает ниже
minSpareThreads, пул пытается создать дополнительный worker заранее - Worker завершает работу по idle timeout только если общее число потоков больше
corePoolSizeи после его ухода останется хотя быminSpareThreadsсвободных потоков
Политика CallerRuns выбрана потому, что благодаря ей задача не теряется и отправитель начинает сам выполнять работу, тем самым естественно замедляя поток новых задач.
Из минусов, поток-отправитель может надолго заняться чужой задачей и растет задержка ответа на стороне вызывающего кода.
Балансировка реализована через Round Robin. Каждая новая задача начинает поиск очереди с очередного индекса. Это распределяет поток задач более равномерно, чем постоянная отправка в первую попавшуюся очередь.
По сравнению со стандартным ThreadPoolExecutor и реализациями Tomcat и Jetty эта реализация ожидаемо проигрывает по эффективности.
- лучший результат обычно достигается когда
corePoolSizeиmaxPoolSizeпримерно равны числу ядер queueSizeлучше держать маленьким, чтобы не накапливать длинную очередь ожиданияminSpareThreadsдостаточно на уровне0или1
Для I/O-bound задач maxPoolSize можно поднимать заметно выше числа ядер
Производительность ухудшают слишком большие queueSize, minSpareThreads, keepAliveTime и слишком маленький keepAliveTime