Java Tomcat servlet应用程序的后台线程

Java Tomcat servlet应用程序的后台线程,java,multithreading,tomcat,Java,Multithreading,Tomcat,我对Tomcat不太熟悉,在我看来它基本上被抽象为一个cgi服务器,可以在调用之间保存JVM——不过我知道它可以做的远不止这些 我正在寻找一种在Tomcat服务器启动时启动后台线程的方法,该线程将定期更新服务器上下文(在我的特殊情况下,这是一个线程,它侦听来自其他一些服务的心跳并更新可用性信息,但可以想象它的各种用途) 有没有标准的方法可以做到这一点?上下文的启动和更新/查询 任何指向相关文档和/或代码示例的指针都将不胜感激。如果要在部署WAR时启动线程,可以在web.xml中定义上下文侦听器:

我对Tomcat不太熟悉,在我看来它基本上被抽象为一个cgi服务器,可以在调用之间保存JVM——不过我知道它可以做的远不止这些

我正在寻找一种在Tomcat服务器启动时启动后台线程的方法,该线程将定期更新服务器上下文(在我的特殊情况下,这是一个线程,它侦听来自其他一些服务的心跳并更新可用性信息,但可以想象它的各种用途)

有没有标准的方法可以做到这一点?上下文的启动和更新/查询


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

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

<web-app>
    <listener>
       <listener-class>com.mypackage.MyServletContextListener</listener-class>
    </listener>
</web-app>
我正在寻找一种在Tomcat服务器启动时启动后台线程的方法

我认为您正在寻找一种在Tomcat启动web应用程序时启动后台线程的方法


这可以用一个简单的方法来完成。它已在web.xml中注册,并将在应用程序启动或停止时调用。然后,您可以使用普通的Java方法创建线程(或ExecutionService),创建(稍后停止)您的线程。

我只需对Chris给出的非常详细的答案做一个小小的更改;我将通过
myThread.setDaemon(true)将
myThread
设置为守护进程线程
这将基本上保持线程活动,只要您有其他需要后台线程的非守护进程线程在工作。当所有这些线程都完成时,JVM会停止守护进程线程,您不需要在
contextdestromed
中自行处理它。
但这只是我的2美分。

1
放入web.xml中的
块将迫使servlet的
init()
在Tomcat启动时立即发生,而不是等待第一个请求到达。如果您想从
init()

生成后台线程,这非常有用。如果您使用的是基于spring的框架,则可以在beans.xml中指定要初始化的类/线程。因此,当tomcat启动时,beans.xml将初始化其中提到的所有类。如果需要,还可以传递构造函数参数。下面是同样的例子

beans.xml

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

啊!!谢谢,这很简单。我说的“ServletContext”是我需要修改的,以使该线程将信息传递给我的servlet,这样它就可以使用我的心跳监听器收集的状态,对吗?是的,我的回答中遗漏了这一部分。:)ServletConText可从ServletContextEvent获得,它可以被传递到your Thread对象中,该对象可以获取/设置所有线程可用的属性,如何访问
MyServletContextListener
来查询线程?值得注意的是,如果有比初始化上下文更方便的地方,通常可以在需要时启动线程。例如,它可能在某个特定servlet的init方法中,或者当某个特定类第一次初始化时,等等。除非您仍然需要在contextDestroyed中处理它。守护进程在最后一个非守护进程线程终止时终止,而不是在servlet上下文终止时终止。如果部署WAR文件来替换当前正在运行的文件,那么来自旧servlet上下文的守护进程线程将继续运行。这反过来又保持了上下文的类加载器,这是一个PermGen内存泄漏,这是很糟糕的。这对我来说是一个诀窍,与这里的其他解决方案相比非常简单,但如此未评级,非常适合启动一些后台应用程序或守护进程。谢谢
<bean id="monitoringSvc" class="com.mypackage.MonitoringService">
    <constructor-arg value="60"></constructor-arg>
</bean>
public class MonitoringService{

     private MyThread myThread;

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