我对Tomcat并不是很熟悉,在我的脑海中,它基本上被抽象为一个cgi服务器,它可以在调用之间保存JVM - 但我知道它可以做的远不止这些。Tomcat servlet应用程序的后台线程
我正在寻找一种方式Tomcat服务器启动时启动背景线程,这将定期更新服务器环境(在我的这个特殊的情况是听一些其他服务和更新的可用性,心跳线程信息,但人们可以想象它有多种用途)。
有没有一个标准的方法来做到这一点? Context的启动和更新/查询都是?
任何指向相关文档和/或代码示例的指针都将非常感谢。
我对Tomcat并不是很熟悉,在我的脑海中,它基本上被抽象为一个cgi服务器,它可以在调用之间保存JVM - 但我知道它可以做的远不止这些。Tomcat servlet应用程序的后台线程
我正在寻找一种方式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) {
}
}
}
啊!谢谢,这非常简单。 我正确地说“ServletContext”是我需要修改的,让这个线程将信息传递给我的servlet,因此它可以使用我的心跳监听器收集的状态? – SquareCog 2009-04-27 01:52:56
是的,在我的答案中错过了这部分。 :) ServletConext可以从ServletContextEvent中获得,它可以传递给你的Thread对象,它可以获取/设置所有线程的属性。 – 2009-04-27 02:07:39
那时,如何访问`MyServletContextListener`来查询线程? – 2016-11-23 15:04:44
我正在寻找一种方式来启动一个后台线程,当一个Tomcat服务器启动
我想你正在寻找一种启动后台线程的方式,你的web应用程序由Tomcat启动。
这可以使用ServletContextListener来完成。它在web.xml中注册,并且会在您的应用程序启动或停止时调用。然后,您可以使用普通的Java方法创建(并稍后停止)线程,以创建线程(或ExecutionService)。
啊,克里斯击败了我.. – Thilo 2009-04-27 01:49:05
我只是对克里斯给出的非常详细的答案做一个小小的修改;我将myThread
设置为一个Daemon线程myThread.setDaemon(true);
,只要您有其他非守护线程工作需要您的后台线程,它就会基本保持线程处于活动状态。当所有这些线程完成后,您的守护程序线程将被JVM停止,您不需要在contextDestroyed
中自行处理它。 但这只是我的2美分。
将<load-on-startup>1</load-on-startup>
置于您的web.xml中的<servlet>
块中会迫使您的servlet的init()
在Tomcat启动后立即发生,而不是等待第一个请求到达。如果你想从init()
产生后台线程,这很有用。
另一种方法,如果您使用基于弹簧的框架,您可以指定要在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();
}
}
值得注意的是,当你想要的时候,你通常可以启动一个线程,如果有比上下文初始化更方便的地方。例如。它可能在特定servlet的init方法中,或者当某个类首先被初始化等。 – 2009-04-27 05:34:36