2009-09-16 12 views
9

En Tomcat, escribí un ServletContextListener que iniciará un ExecutorService durante el inicio y lo terminará cuando se descargue.Apagar un ExecutorService

estoy siguiendo el ejemplo en el Javadoc para ExecutorService

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

Mi pregunta es debería propagar la InterruptedException en el método contextDestroyed()?

+1

¿Su ejecutor se cierra? El mío no parece que use este mismo código ... (y muchos más enfoques) – SoulWanderer

+0

El mío tampoco se cierra con el mismo código. Yo uso tomcat 7 – lili

Respuesta

4

Yo diría que no. El contenedor llama al método contextDestroyed como una notificación de que el contexto está a punto de ser derribado, no le está pidiendo permiso. Además, el Javadoc no define qué sucede si arrojas una excepción, por lo que los resultados pueden ser impredecibles y/o no portátiles.

Lo que haría es llamar al executor.shutdownNow() dentro del bloque catch para terminar por la fuerza el ejecutor (es decir, "usted tuvo la oportunidad, ahora pare").

+0

Si es "impredecible", ¿qué es lo peor que podría pasar si se produce una excepción? –

+0

+1 spot-on con la recomendación shutDownNow(). Absorber la excepción y establecer la bandera aquí es realmente lo correcto. –

+0

En el peor de los casos, el código que ejecuta esa devolución de llamada no lo detecta y falla un hilo. Sin embargo, lo más importante es pensar en qué indica la excepción que proviene de "awaitTermination()". Todas las excepciones significan que el hilo no pudo seguir esperando a que todos los hilos terminaran porque fue interrumpido por otro hilo, lo que indica que debería terminar. Si no hubiera realizado una llamada de bloqueo, la bandera de interrupción se habría configurado en segundo plano y ni siquiera lo sabría. Así que lo correcto aquí es establecer la bandera, es terminar el ejecutor y establecer la bandera. –

1

Lo que tienes en tu muestra de código (vuelve a interrumpir el hilo actual) es exactamente lo que yo recomendaría. Algo en Tomcat fuera de su propio código envió la interrupción original, así que deje que Tomcat tenga la oportunidad de manejarlo.

No sé qué hará Tomcat con la InterruptedException. No está definido Pero Tomcat inició la interrupción y Tomcat posee el hilo en el que se está ejecutando el método contextDestroyed (...). El principio general de "Java Concurrency in Practice" que se aplica aquí es: el creador del hilo es responsable de manejar la vida útil del hilo. Cylce problemas.

Manejar una interrupción es definitivamente un problema de ciclo de vida.

+0

¿Sabes qué hará Tomcat con la InterruptedException? –

0

Estoy de acuerdo con Steve, restablecer el indicador de interrupción da el código fuera de su control la oportunidad de reaccionar al evento.

tempus fugit-ofrece un método convieance para hacer esto para usted, junto con una excepción de tiempo de espera explict si las cosas toman mucho tiempo.

waitOrTimeout(shutdown(executor), timeout); 

Tenga una mirada en la sección de concurrencia de los documentos si es de interés ... tempusfugitlibrary.org/documentation

Este example demuestra su uso, tanto para la espera de la finalización y el cierre más agresivo.