Подтвердить что ты не робот

Выключить ExecutorService изящно в webapp?

В моем webapp я создал службу, которая использует ExecutorService с фиксированным размером ThreadPool. Я использую один и тот же ExecutorService в течение всего срока службы приложения.

private static ExecutorService pool = Executors.newFixedThreadPool(8);

Все работает в Tomcat, что дает мне следующую ошибку при отключении:

appears to have started a thread named [pool-1-thread-1] but has failed to stop it. This is very likely to create a memory leak.

Я понимаю, что мне нужно выключить ExecutorService, прежде чем отключить tomcat. Soms SO thread уже говорит об этом, но я не мог найти чистый способ справиться с этим.

Должен ли я использовать ShutdownHook как предложено @Tim-bender в Изящное завершение потоков и исполнителей? Или я должен использовать CachedThreadPool?

4b9b3361

Ответ 1

Завершающий крючок не подходит для Tomcat, потому что:

  • он закроет пул слишком поздно (при выключении), Tomcat уже предупредит вас о не закрытых ресурсах

  • вы действительно хотите закрыть этот пул, когда приложение не развернуто, так что перераспределение работает (иначе каждое приложение создаст новый пул, и все они будут закрыты только при полном завершении работы)

  • Завершение пула потоков может занять некоторое время (см. ниже), крюк отключения должен быть как можно быстрее

Намного лучше - ServletContextListener.contextDestroyed(). Помните, что у вас есть как shutdownNow() пул (чтобы отменить запуск и отклонить новые задачи), так и awaitTermination(), чтобы дождаться завершения уже запущенных задач и остановить все потоки.

Ответ 2

В дополнение к тому, что предложил Томаш, вы также можете использовать CachedThreadPool

Нити, которые не использовались в течение шестидесяти секунд, завершаются и удаляются из кеша. Таким образом, пул, который остается бездействующим достаточно долго, не будет потреблять какие-либо ресурсы

Таким образом, очень хорошим решением будет использование CachedThreadPool и выключение его в ServletContextListener.contextDestroyed().