2012-10-10 54 views
22

En mi aplicación web, creé un servicio que usa un ExecutorService con ThreadPool de tamaño fijo. Reutilizo el mismo ExecutorService durante toda la vida útil de la aplicación.Shutdown ExecutorService correctamente en webapp?

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

Todo se ejecuta en Tomcat que me da el siguiente error al shuting abajo:

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. 

Me doy cuenta que necesito para apagar el ExecutorService antes shuting Tomcat hacia abajo. El hilo Soms SO ya habla de esto, pero no pude encontrar una manera limpia de manejar esto.

¿Debo usar un ShutdownHook como lo sugirió @ Tim-bender en Graceful shutdown of threads and executor? ¿O debería usar un CachedThreadPool en su lugar?

Respuesta

25

gancho de cierre no es un buen enfoque en Tomcat porque:

  • se va a cerrar la piscina demasiado tarde (en el cierre), Tomcat ya se le advertirá acerca de los recursos no cerradas

  • que

    realidad desea cerrar ese grupo cuando la aplicación no se despliega para que funcione la redistribución (de lo contrario, cada aplicación creará un grupo nuevo y se cerrarán solo al finalizar por completo)

  • apagando el hilo piscina podría tomar algún tiempo (véase más adelante), el gancho de cierre debe ser lo más rápido posible

Mucho mejor lugar es ServletContextListener.contextDestroyed(). Recuerde que tiene que shutdownNow() el grupo (para cancelar la ejecución y rechazar nuevas tareas) y awaitTermination() para esperar a que las tareas que ya se están ejecutando finalicen y que todos los hilos se detengan.

+1

Exactamente lo que necesitaba saber –

7

Además de lo que sugirió Tomasz también se puede utilizar CachedThreadPool

Temas que no han sido utilizados durante sesenta segundos están terminados y removidos del cache. De este modo, una piscina que permanece inactivo durante el tiempo suficiente no consume recursos

lo tanto una muy buena solución sería utilizar CachedThreadPool y apagado en ServletContextListener.contextDestroyed().

+4

+1 felicidades por 5K –

+0

@NandkumarTekale Gracias. Se ve bien :) –

Cuestiones relacionadas