Как работает метод shutdown у ExecutorService в Java
Что проверяют
Понимаете ли вы, что shutdown() только закрывает приём задач и ничего не ждёт, и умеете ли корректно погасить пул при остановке приложения. Следом почти всегда просят сравнить с shutdownNow() и написать правильную последовательность завершения.
Как отвечать
После shutdown() пул переходит в состояние SHUTDOWN:
- новые задачи:
execute()иsubmit()отклоняются черезRejectedExecutionHandler, уThreadPoolExecutorпо умолчанию этоRejectedExecutionException; - уже принятые задачи: выполняются все, включая те, что ещё лежат в очереди и не стартовали;
- вызывающий поток: не блокируется, метод возвращается сразу. Повторный вызов ничего не делает;
- ожидание:
awaitTermination(timeout, unit)блокирует до завершения или таймаута и возвращаетboolean,isTerminated()показывает итог.
shutdownNow() жёстче: вызывает interrupt() у рабочих потоков, выбрасывает очередь и возвращает её как List<Runnable>. Прерывание это просьба, а не убийство потока: задача, которая не проверяет флаг и не блокируется на прерываемых вызовах, доработает до конца.
Каноничная схема: shutdown(), затем awaitTermination с таймаутом, при false вызвать shutdownNow() и подождать ещё раз. Если ожидание прервали, тоже shutdownNow() и восстановить флаг через Thread.currentThread().interrupt(). С Java 19 ExecutorService реализует AutoCloseable, и close() делает то же самое в try-with-resources, это удобно с Executors.newVirtualThreadPerTaskExecutor().
У ScheduledThreadPoolExecutor есть нюанс: после shutdown() периодические задачи по умолчанию отменяются, а отложенные разовые выполняются.
Где спотыкаются
Считают, что shutdown() ждёт окончания задач, и сразу после вызова читают результаты или закрывают ресурсы, которыми задачи ещё пользуются.
Думают, что задачи из очереди при shutdown() теряются. Теряются они при shutdownNow(), и возвращённый список обычно стоит залогировать.
Не вызывают завершение вовсе. Потоки фиксированного пула не демоны, поэтому JVM не завершится, а в веб-приложении при передеплое останутся висящие потоки.