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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/791986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:32:23  来源:igfitidea点击:

Background Thread for a Tomcat servlet app

javamultithreadingtomcat

提问by SquareCog

I am not very familiar with Tomcat, in my head it is basically abstracted as a cgi server that saves the JVM between calls -- I know it can do a lot more than that, though.

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

I am looking for a way to launch a backgroundthread when a Tomcat server starts, which would periodically update the Server Context (in my particular case this is a thread that listens to heartbeats from some other services and updates availability information, but one can imagine a variety of uses for this).

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

Is there a standard way to do this? Both the launching, and the updating/querying of the Context?

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

Any pointers to the relevant documentation and/or code samples would be much appreciated.

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

采纳答案by Chris Thornhill

If you want to start a thread when your WAR is deployed, you can define a context listener within the web.xml:

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

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

Then implement that class something like:

然后实现该类,例如:

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) {
        }
    }
}

回答by Thilo

I am looking for a way to launch a background thread when a Tomcat server starts

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

I think you are looking for a way to launch a background thread when your web applicationis started by Tomcat.

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

This can be done using a ServletContextListener. It is registered in web.xml and will be called when your app is started or stopped. You can then created (and later stop) your Thread, using the normal Java ways to create a Thread (or ExecutionService).

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

回答by Ittai

I'd just make a small change to the very detailed answer Chris gave; I would set myThreadto be a Daemon thread by myThread.setDaemon(true);which will basically keep the thread active as long as you have other non-Daemon threads working which need your background thread around. When all these threads finish then your Daemon thread is stopped by the JVM and you do not need to handle it youself in contextDestroyed. But that's just my 2 cents.

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

回答by divbyzero

Putting <load-on-startup>1</load-on-startup>in the <servlet>block in your web.xml will force your servlet's init()to happen as soon as Tomcat starts up, rather than waiting for the first request to arrive. This is useful if you want to spawn the background thread from init().

<load-on-startup>1</load-on-startup><servlet>在web.xml将迫使你的servlet块是init()为Tomcat的启动,一旦发生,而不是等待到达的第一条请求。如果您想从init().

回答by Akshay

Another way if you are using spring based framework you can specify the class/thread which you want to initialize in the beans.xml. So when the tomcat starts up, beans.xml will initialize all the classes mentioned in it. You can also pass constructor arguments if required. Below is the example of the same.

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

beans.xml

bean.xml

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

MonitoringService.java

监控服务.java

public class MonitoringService{

     private MyThread myThread;

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