有人能给些建议吗?我有这样一种情况,用户将通过Java JSP和servlet交互式提交数据挖掘请求到我的应用程序中,该应用程序将动态地处理数据关联规则等内容。
由于这样的任务可能需要一些时间,我正在考虑在服务器上运行一些进程来在后台运行此类请求,以避免“锁定”会话并可能对系统造成大量内存使用的不利影响。
由于该系统是由一系列运行在Tomcat容器中的Java JSP和servlet组成的,并且使用MySQL数据库,有人可以提出解决方案吗?
谢谢
Morgan先生
有人能给些建议吗?我有这样一种情况,用户将通过Java JSP和servlet交互式提交数据挖掘请求到我的应用程序中,该应用程序将动态地处理数据关联规则等内容。
由于这样的任务可能需要一些时间,我正在考虑在服务器上运行一些进程来在后台运行此类请求,以避免“锁定”会话并可能对系统造成大量内存使用的不利影响。
由于该系统是由一系列运行在Tomcat容器中的Java JSP和servlet组成的,并且使用MySQL数据库,有人可以提出解决方案吗?
谢谢
Morgan先生
但是,有几件事情需要注意,将线程标记为守护线程,这样至少在错误场景下不会阻塞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>
ExecutorService executor = (ExecutorService )getServletContext().getAttribute("MY_EXECUTOR");
...
executor.submit(myJob);
while(true){Thread.sleep(1000); // do something more..}
的run方法,对吧? - DéboraServletContextListener
接口的类来启动和关闭您的ExecutorService
。该执行程序有方法可以优雅地关闭您的执行线程(shutdown
),或者尝试更粗暴的中断(shutdownNow
)。我在开发过程中遇到过一些关闭问题(NetBeans混合使用Tomcat和JRebel),但在生产环境中没有遇到过。 - Basil Bourque也许JMS是您真正需要的,但是在Tomcat上使用它需要额外的努力,因为它只是Servlet容器。您可以切换到真正的应用服务器,如Glassfish或JBoss,也可以自己添加JMS功能到Tomcat中(参考下面的链接)
http://blogs.captechconsulting.com/blog/jairo-vazquez/tomcat-and-jms