Вопрос с собеседования · Java

Почему фабрики из класса Executors считают опасными в production-коде?

MiddleМногопоточность
Ещё спрашивают так:
  • Как выбрать параметры пула потоков для сервиса и чем опасны фабрики Executors?
  • Как выбрать параметры пула потоков для сервиса и чем опасны фабрики Executors.newFixedThreadPool и newCachedThreadPool?
Коротко

Скрытые неограниченные ресурсы: newFixedThreadPool — неограниченная очередь (задачи копятся до OutOfMemoryError, наружу не идёт никакого отказа), newCachedThreadPool — неограниченное число потоков (тысячи потоков под всплеском). В проде ThreadPoolExecutor создают явно.

  • Ограниченная очередь (ArrayBlockingQueue)
  • Осмысленная политика отказа: CallerRunsPolicy даёт естественное торможение
  • Именованная ThreadFactory — читаемые дампы потоков

А ещё Метрики: размер очереди, активные потоки, отказы

Попробуйте сами

Очередь и утилизация: почему при 90% всё тормозит

Подробно

newFixedThreadPool и newSingleThreadExecutor берут LinkedBlockingQueue без границы: при всплеске нагрузки очередь растёт, пока не кончится куча, причём деградация не видна по метрикам пула. newCachedThreadPool использует SynchronousQueue и лимит потоков в Integer.MAX_VALUE — под нагрузкой это взрыв числа потоков. Правильный путь — создать ThreadPoolExecutor напрямую: ограниченная ArrayBlockingQueue, осмысленный RejectedExecutionHandler (CallerRunsPolicy даёт естественное торможение) и именованная ThreadFactory для читаемых стектрейсов.

Что хотят услышать

  • Неограниченная очередь fixed и неограниченные потоки cached.
  • Явный ThreadPoolExecutor с ограниченной очередью и политикой отказа.
  • Очередь важнее размера пула.

Частые ошибки

  • Считать fixed-пул безопасным, потому что число потоков ограничено — опасна очередь.
  • Оставлять политику отказа по умолчанию, не подумав, что делать с отвергнутой задачей.

Проверьте себя

Несколько верных вариантов. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓newFixedThreadPool использует неограниченную очередь: при перегрузке задачи копятся до OutOfMemoryError
  • ✗Эти фабрики не поддерживают Callable, только Runnable, поэтому результат задачи получить нельзя
  • ✓newCachedThreadPool может создать практически неограниченное число потоков
  • ✓Надёжнее конструировать ThreadPoolExecutor явно — с ограниченной очередью и политикой отказа

Что спросят дальше

  • Что делает CallerRunsPolicy и почему она полезна?
  • Как выбрать размер пула?
  • Что меняют виртуальные потоки в этом рассуждении?
  • Как выбрать между CallerRunsPolicy и AbortPolicy?

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования