2012-10-10 12 views
22

In meiner Webanwendung habe ich einen Dienst erstellt, der einen ExecutorService mit ThreadPool fester Größe verwendet. Ich verwende das gleiche ExecutorService während der gesamten Anwendungslebenszeit.ExecutorService elegant in webapp herunterfahren?

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

Alle in Tomcat ausgeführt wird, die mir die folgende Fehlermeldung gibt, während shuting nach unten:

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. 

ich erkennen, ich brauche die ExecutorService zum Herunterfahren, bevor unten tomcat shuting. SOMS-Thread spricht bereits darüber, aber ich konnte keinen sauberen Weg finden, damit umzugehen.

Sollte ich eine ShutdownHook wie vorgeschlagen @ Tim-Bender in Graceful shutdown of threads and executor verwenden? Oder sollte ich stattdessen einen CachedThreadPool verwenden?

Antwort

25

Shutdown Haken ist kein guter Ansatz in Tomcat, weil:

  • es wird auf den Pool zu spät (beim Herunterfahren) schließen, Tomcat werden Sie bereits warnen vor nicht geschlossen Ressourcen

  • Sie tatsächlich möchte diesen Pool herunterfahren, wenn die Anwendung nicht bereitgestellt wird, so dass die erneute Bereitstellung funktioniert (andernfalls erstellt jede Anwendung einen neuen Pool und sie werden erst beim vollständigen Herunterfahren geschlossen)

    den Thread herunterfahren Pool könnte einige Zeit (siehe unten), shutdown Haken sollte so schnell wie möglich

viel besseren Ort ist ServletContextListener.contextDestroyed() nehmen. Denken Sie daran, Sie müssen sowohl shutdownNow() der Pool (um abzubrechen ausgeführt werden und neue Aufgaben ablehnen) und awaitTermination() warten auf bereits laufende Aufgaben zu beenden und alle Threads zu stoppen.

+1

Genau das, was ich wissen musste –

7

Zusätzlich zu dem, was Tomasz vorgeschlagen können Sie auch CachedThreadPool

Threads verwenden, die aus dem Cache für 60 Sekunden verwendet haben, werden beendet und nicht entfernt worden. Somit ist ein Pool, der lange genug im Leerlauf bleibt verbraucht keine Ressourcen

So eine sehr gute Lösung wäre CachedThreadPool und Herunterfahren verwendet es in ServletContextListener.contextDestroyed().

+4

+1 Herzlichen Glückwunsch für 5K –

+0

@NandkumarTekale Danke. Es sieht gut aus :) –