在webapp中正常关闭ExecutorService?

时间:2012-10-10 08:59:03

标签: java multithreading tomcat6 executorservice

在我的webapp中,我创建了一个使用固定大小ThreadPool的ExecutorService的服务。我在整个应用程序生命周期中重用了相同的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.

我确实意识到我需要在关闭tomcat之前关闭ExecutorService。 Soms SO线程已经谈到了这一点,但我找不到一个干净的方法来解决这个问题。

我应该在Graceful shutdown of threads and executor中使用@ Tim-bender建议的ShutdownHook吗?或者我应该使用CachedThreadPool吗?

2 个答案:

答案 0 :(得分:25)

关闭挂钩在Tomcat中不是一个好方法,因为:

  • 它会关闭池太迟(关闭时),Tomcat已经警告过你没有关闭资源

  • 您实际上想要在取消部署应用程序时关闭该池,以便重新部署工作(否则每个应用程序将创建新池,并且只有在完全关闭时它们才会关闭)

  • 关闭线程池可能需要一些时间(见下文),关闭钩子应该尽可能快

更好的地方是ServletContextListener.contextDestroyed()。请记住,您必须同时shutdownNow()池(取消运行并拒绝新任务)和awaitTermination()等待已经运行的任务完成并且所有线程都要停止。

答案 1 :(得分:7)

除了Tomasz建议您还可以使用CachedThreadPool

  

未使用60秒的线程终止并从缓存中删除。因此,长时间闲置的池不会消耗任何资源

所以一个非常好的解决方案是使用CachedThreadPool并在ServletContextListener.contextDestroyed()中关闭它。