在Tomcat中运行后台Java程序

任何人都可以在这里build议? 我有一种情况,用户将通过Java JSP和servlet交互式地提交数据挖掘请求到我的应用程序,这个应用程序将dynamic地处理关于数据和更多的关联规则。

由于这样的工作可能需要一段时间,我正考虑在服务器上的某种进程在后台运行这样的请求,所以它不会locking会话,并可能使用大量的服务器内存来损害的系统。

由于系统是由一系列在JSP数据库上运行的Tomcat容器中的Java JSP和Servlet组成的,任何人都可以提出一个前进的方向吗?

谢谢

摩根先生

使用一个ExecutorService 。

有几件事你应该做,把线程标记为一个守护进程线程,所以它至less不会在错误情况下捆绑tomcat,并且当你的servlet上下文被销毁时,你应该停止执行器(例如,当你重新部署或停止你的应用程序。要做到这一点,使用一个ServletContextListener:

public class ExecutorContextListener implements ServletContextListener { private ExecutorService executor; public void contextInitialized(ServletContextEvent arg0) { ServletContext context = arg0.getServletContext(); int nr_executors = 1; ThreadFactory daemonFactory = new DaemonThreadFactory(); try { nr_executors = Integer.parseInt(context.getInitParameter("nr-executors")); } catch (NumberFormatException ignore ) {} if(nr_executors <= 1) { executor = Executors.newSingleThreadExecutor(daemonFactory); } else { executor = Executors.newFixedThreadPool(nr_executors,daemonFactory); } context.setAttribute("MY_EXECUTOR", executor); } public void contextDestroyed(ServletContextEvent arg0) { ServletContext context = arg0.getServletContext(); executor.shutdownNow(); // or process/wait until all pending jobs are done } } import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; /** * Hands out threads from the wrapped threadfactory with setDeamon(true), so the * threads won't keep the JVM alive when it should otherwise exit. */ public class DaemonThreadFactory implements ThreadFactory { private final ThreadFactory factory; /** * Construct a ThreadFactory with setDeamon(true) using * Executors.defaultThreadFactory() */ public DaemonThreadFactory() { this(Executors.defaultThreadFactory()); } /** * Construct a ThreadFactory with setDeamon(true) wrapping the given factory * * @param thread * factory to wrap */ public DaemonThreadFactory(ThreadFactory factory) { if (factory == null) throw new NullPointerException("factory cannot be null"); this.factory = factory; } public Thread newThread(Runnable r) { final Thread t = factory.newThread(r); t.setDaemon(true); return t; } } 

您必须将上下文侦听器添加到您的web.xml中,您还可以在其中指定要运行后台作业的线程数:

  <listener> <listener-class>com.example.ExecutorContextListener</listener-class> </listener> 

您可以从您的servlet访问执行程序并提交作业:

 ExecutorService executor = (ExecutorService )getServletContext().getAttribute("MY_EXECUTOR"); ... executor.submit(myJob); 

如果你使用Spring,所有这些都可能变得更简单

我认为Quartz调度器应该能够完成你想在这里做的事情。 这里是一些来自Quartz的例子 。 使用这个,您可以启动一个快速轮询来处理传入请求的cron。 我其实是为我的一个项目做的。

一个轻量级的解决scheme(与使用石英这样的调度器相反)是将处理放到后台线程中,并通过ExecutorService运行。

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

也许JMS是你真正想要的,但是它需要额外的努力来使用Tomcat,因为它只是Servlet容器。 您可以切换到像Glassfish或JBoss一样的真正的AppServer,或者通过您自己的方式向Tomcat添加JMSfunction(下面的链接)

http://blogs.captechconsulting.com/blog/jairo-vazquez/tomcat-and-jms