有谁可以在这里提出建议?我有一种情况,用户将通过Java JSP和servlet以交互方式将数据挖掘请求提交给我的应用程序,该应用程序将动态地计算出关于数据的关联规则等.
因为这样的工作可能需要一段时间,我想在服务器上运行某种过程以在后台运行这样的请求,所以它不会"锁定"会话并可能使用大量的服务器内存而造成损害系统的.
由于系统由在MySQL数据库上运行在Tomcat容器中的一系列Java JSP和servlet组成,任何人都可以建议前进的方向吗?
谢谢
摩根先生
我有一个部署到Tomcat服务器的WAR文件,其中一个类将在启动时调用,然后init()方法将安排一个计时器每5小时触发一次以执行某些任务.
我的init()代码如下所示:
public void init()
{
TimerTask parserTimerTask = new TimerTask() {
@Override
public void run() {
XmlParser.parsePage();
}
};
Timer parserTimer = new Timer();
parserTimer.scheduleAtFixedRate(parserTimerTask, 0, PERIOD);
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序运行没有问题,但当我使用/etc/init.d/tomcat7停止关闭Tomcat时,我检查日志(catalina.out)它有一个这样的条目:
严重:Web应用程序[/ MyApplication]似乎已经启动了一个名为[Timer-0]的线程,但未能阻止它.这很可能造成内存泄漏.
我明白这是由我安排计时器引起的,但我的问题是:
setDeamon为true,所以定时器不应该阻止Tomcat关闭,而不是继续运行?谢谢!
UPDATE
我根据一些搜索和DaveHowes的答案将我的代码更改为以下内容.
Timer parserTimer;
TimerTask parserTimerTask;
public void init()
{
parserTimerTask = new TimerTask() {
@Override
public void run() {
XmlParser.parsePage();
}
};
parserTimer = new Timer();
parserTimer.scheduleAtFixedRate(parserTimerTask, 0, PERIOD);
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
Logger logger …Run Code Online (Sandbox Code Playgroud) 正如它在javadoc中所说的那样
池中的线程将一直存在,直到它被显式关闭为止
ExecutorService#shutdown()
如果我在Tomcat上有一个Web应用程序.启动时它会创建一个固定的线程池.我也调查过了
public static void main(String ... strings) {
ExecutorService s = Executors.newFixedThreadPool(2);
s.submit(new Runnable() {
public void run() {
System.out.println("zzz");
}
});
}
Run Code Online (Sandbox Code Playgroud)
在我将它们提交给ExecutorService之前,上述示例中的线程不存在.当main方法结束时,我javaw.exe在任务管理器的进程列表中看到一个(win 7 os).所以我假设运行该示例的jvm实例仍然存在.当我添加时s.shutdown()- 进程列表中没有任何java进程.
问题1:当tomcat由于某些错误突然停止时,java进程会挂起内存(如果以前有些任务被提交到上面提到的线程池);
问题2:如果上一个问题的答案是肯定的,是否有一些方法可以使池中的线程成为deamon,或者有一些方法可以处理这样的tomcat/myapp停止调用ExecutorService#shutdown()