Tomcat servlet应用程序的后台线程

我对Tomcat不是很熟悉,在我的脑海里,它基本上被抽象为一个cgi服务器,可以在调用之间保存JVM,不过我知道它可以做的更多。

我正在寻找一种方式来启动后台线程,当一个Tomcat服务器启动,这将周期性地更新服务器上下文(在我的情况下,这是一个线程,侦听来自其他服务的心跳,并更新可用性信息,但可以想象为此的各种各样的用途)。

有没有一个标准的方法来做到这一点? Context的启动和更新/查询都是?

任何指向相关的文档和/或代码示例的指针将非常感激。

如果要在部署WAR时启动线程,则可以在web.xml中定义一个上下文侦听器:

<web-app> <listener> <listener-class>com.mypackage.MyServletContextListener</listener-class> </listener> </web-app> 

然后执行该类,如下所示:

 public class MyServletContextListener implements ServletContextListener { private MyThreadClass myThread = null; public void contextInitialized(ServletContextEvent sce) { if ((myThread == null) || (!myThread.isAlive())) { myThread = new MyThreadClass(); myThread.start(); } } public void contextDestroyed(ServletContextEvent sce){ try { myThread.doShutdown(); myThread.interrupt(); } catch (Exception ex) { } } } 

我正在寻找一种在Tomcat服务器启动时启动后台线程的方法

我想你正在寻找一种方式来启动一个后台线程,当你的Web应用程序由Tomcat启动。

这可以通过使用ServletContextListener来完成。 它在web.xml中注册,当你的应用程序启动或停止时会被调用。 然后,您可以创build(并稍后停止)您的线程,使用普通的Java方法来创build线程(或ExecutionService)。

<load-on-startup>1</load-on-startup>放在web.xml中的<servlet>块中会强制servlet的init()在Tomcat启动时立即发生,而不是等待第一个请求到达。 如果你想从init()产生后台线程,这是很有用的。

我只是对克里斯给出的非常详细的答案做一个小改动, 我将通过myThread.setDaemon(true);myThread设置为守护程序线程myThread.setDaemon(true); 这将基本上保持线程活动,只要你有其他非守护线程工作,需要你的后台线程。 当所有这些线程完成后,你的Daemon线程被JVM停止,你不需要在contextDestroyed自己处理它。 但那只是我的2美分。

另一种方法,如果你使用基于spring的框架,你可以指定你想在beans.xml中初始化的类/线程。 所以当tomcat启动时,beans.xml将会初始化其中提到的所有类。 如果需要,您也可以传递构造函数参数。 下面是同样的例子。

beans.xml中

 <bean id="monitoringSvc" class="com.mypackage.MonitoringService"> <constructor-arg value="60"></constructor-arg> </bean> 

MonitoringService.java

 public class MonitoringService{ private MyThread myThread; public MonitoringService(int seconds){ myThread = new MyThread(seconds); myThread.start(); } }