9

В Tomcat я написал ServletContextListener, который запустит ExecutorService во время запуска и завершит его, когда он будет выгружен.Завершение работы ExecutorService

Я следую примеру в Javadoc для ExecutorService

public void contextDestroyed(ServletContextEvent sce) 
{ 
    executor.shutdown(); 
    try 
    { 
     executor.awaitTermination(50, TimeUnit.SECONDS); 
    } 
    catch(InterruptedException ie) 
    { 
     Thread.currentThread().interrupt(); 
    } 
} 

Мой вопрос я должен распространять InterruptedException в методе contextDestroyed()?

+1

Закрыт ли ваш исполнитель? Шахта не althougt я использовал тот же код ... (и многие другие подходы) – SoulWanderer

+0

Mine не закрывается ни тем же кодом. Я использую tomcat 7 – lili

ответ

4

Я бы сказал, нет. Метод contextDestroyed вызывается контейнером в качестве уведомления о том, что контекст будет разорван, он не запрашивает ваше разрешение. Кроме того, Javadoc не определяет, что произойдет, если вы выбросите из него исключение, поэтому результаты могут быть непредсказуемыми и/или не переносимыми.

Что бы я хотел сделать, это позвонить executor.shutdownNow() внутри блока catch, чтобы принудительно прекратить выполнение исполнителем (т. Е. «У вас был шанс, теперь остановитесь»).

+0

Если это «непредсказуемо», что самое страшное, что может произойти, если вызывается исключение? –

+0

+1 пятно с рекомендацией shutDownNow(). Абсорбирование исключения и установка флага здесь - это действительно то, что нужно сделать. –

+0

Худший случай, код, выполняющий этот обратный вызов, не захватывает его, и поток падает. Что еще более важно, подумайте о том, что означает исключение, исходящее из «awaitTermination()». Все исключение означает, что поток не может продолжать ждать завершения всех потоков, потому что он был прерван другим потоком, указывая, что он должен завершиться. Если бы вы не сделали блокирующий вызов, флаг прерывания был бы установлен в фоновом режиме, и вы даже не знали бы об этом. Поэтому здесь нужно установить флаг, прекратить выполнение и установить флаг. –

1

Что вы имеете в своем примере кода (повторное прерывание текущего потока) - это именно то, что я бы рекомендовал. Что-то в Tomcat вне вашего собственного кода отправило оригинальное прерывание, поэтому пусть Tomcat имеет возможность обработать его.

Я не знаю, что Tomcat будет делать с InterruptedException. Это не определено. Но Tomcat инициировал прерывание, а Tomcat владеет потоком, в котором работает метод contextDestroyed (...). Общий принцип использования Java Concurrency in Practice, который применяется здесь, заключается в том, что создатель потока отвечает за обработку потоков, вопросы о цикле.

Обработка прерывания, безусловно, является проблемой жизненного цикла.

+0

Знаете ли вы, что Tomcat будет делать с InterruptedException? –

0

Я согласен со Стивом, сброс флага прерывания дает код вне вашего контроля, чтобы реагировать на событие.

tempus-fugit предлагает метод convieance для этого для вас, а также исключение исключения тайм-аута, если вещи занимают слишком много времени.

waitOrTimeout(shutdown(executor), timeout); 

Посмотрите в разделе параллелизмом из документации, если его интересов ... tempusfugitlibrary.org/documentation

example Это демонстрирует его использование, как для ожидающих завершения и более агрессивное выключение.

Смежные вопросы