简体   繁体   中英

How to run long running process using servlet

I have a situation where I need to start a task which runs for 4 hours. I am using servlet to kick off the process. However I am getting a memory leak exception.

Aug 10, 2016 2:08:05 PM org.apache.catalina.core.StandardContext reload
INFO: Reloading Context with name [/] has started
Aug 10, 2016 2:08:05 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 1 instance(s) to be deallocated for Servlet [Servlet]
Aug 10, 2016 2:08:06 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 1 instance(s) to be deallocated for Servlet [Servlet]
Aug 10, 2016 2:08:07 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 1 instance(s) to be deallocated for Servlet [DayZeroServlet]
Aug 10, 2016 2:08:07 PM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
WARNING: The web application [xxx#Day0MS] is still processing a request that has yet to finish. This is very likely to create a memory leak. You can control the time allowed for requests to finish by using the unloadDelay attribute of the standard Context implementation. Stack trace of request processing thread:
java.net.SocketOutputStream.socketWrite0(Native Method)
java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)

Below is the code, I am using

protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    PrintWriter out = response.getWriter();
    if (!GehDAO.getProcessFlag()) {
        GehDAO.updateProcessFlag(true);
        out.println("Transformation started  ...");
        closeWriter(out);
        execute();  // This step start the long running process
    }
    else {
        out.println("Transformation Already Running  ...");
        closeWriter(out);
    }
}

Is there a way i can run the execute() method in separate process?

I wanted to run this servlet once or twice in a month, to kick off long running process.

Can't you just wrap the execute() call into a thread?

new Thread(() -> execute()).start();

Or for older pre-Java8:

new Thread(new Runnable() {
    public void run() { execute(); }
}).start();

One side note: Make sure you manage the shutdown. You can usually do this with a ServletContextListener . Basically, if the context is destroyed, set a boolean flag on your long running thread to let it know that it needs to stop because the app server is waiting on it to finish in order to shut down.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM