2016-08-10 99 views
0

我遇到需要启动运行4小时的任务的情况。我正在使用servlet来启动流程。但是我收到一个内存泄漏异常。如何使用servlet运行长时间运行的进程

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) 

下面是代码,我使用

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

有没有一种方法,我可以运行在单独的进程中execute()方法?

我想在一个月内运行一次或两次这个servlet,以启动长时间运行的进程。

+0

请注意,您的代码不是线程安全的。 – xehpuk

回答

1

难道你不能只将​​调用包装到线程中吗?

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

或者对老年人预Java8:

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

一个侧面说明:请确保您管理关机。你通常可以用ServletContextListener来做到这一点。基本上,如果上下文被破坏,请在长时间运行的线程上设置一个布尔标志,让它知道它需要停止,因为应用程序服务器正在等待它关闭。

+0

基本上这个。分叉一个新的线程,让它旋转。如果您审核其任务的进度,以便他们可以监控其进度,则从最终用户获得奖励积分;我发现MongoDB适合存储类似的东西,但任何其他数据库都可以工作。此外,使用数据库将允许您实现任务队列,以便您的用户不会旋转十​​八亿个并行线程。 – nasukkin

相关问题