我已将一个WAR文件部署到Tomcat服务器,该类之一将在启动时调用,然后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);
}
我的应用程序运行没有问题,但是当我使用 /etc/init.d/tomcat7 stop
关闭Tomcat时,我检查了日志(catalina.out),它具有以下条目:
严重:Web应用程序[/ MyApplication]似乎已启动名为[Timer-0]的线程,但未能停止它。 这很可能造成内存泄漏。
我了解这是由我安排计时器引起的,但我的问题是:
setDeamon
为true,所以计时器是否不应该阻止Tomcat关闭而不是保持运行?谢谢!
更新
根据一些搜索和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 = Logger.getRootLogger();
logger.info("DETECT TOMCAT SERVER IS GOING TO SHUT DOWN");
logger.info("CANCEL TIMER TASK AND TIMER");
otsParserTimerTask.cancel();
otsParserTimer.cancel();
logger.info("CANCELING COMPLETE");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
}
现在我的新问题是:
谢谢!
更新
没用 我将一些日志记录语句放入contextDestroyed()方法中,在关闭Tomcat之后,日志文件仅具有以下内容:
PowderGodAppWebService-> [2012年2月7日04:09:46
PM]信息(PowderGodAppWebService.java:45):: DETECT
TOMCAT服务器即将关闭PowderGodAppWebService-> [2012年2月7日04:09:46 PM]
INFO(PowderGodAppWebService。 java:46)::取消计时器任务和计时器
取消完成 不存在。
我还检查了正在运行的进程(我不是Linux专家,所以我只使用Mac的活动监视器。
固定
我将代码更改为,parserTimer = new Timer(true);
以便计时器作为守护程序线程运行,因为contextDestroyed()
在Tomcat实际上关闭后调用了gets。
“在通知任何ServletContextListener上下文破坏之前,所有Servlet和过滤器都将被破坏。”
http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html
千万 不能 使用Timer
在Java
EE的环境!如果任务抛出运行时异常,则整个Timer
事件将被杀死,并且将不再运行。基本上,您需要重新启动整个服务器才能使其再次运行。而且,它对系统时钟的变化很敏感。
使用ScheduledExecutorService
代替。它对任务中引发的异常或系统时钟的更改不敏感。您可以通过其shutdownNow()
方法关闭它。
这是整个ServletContextListener
实现的示例(请注意:web.xml
由于有了新的@WebListener
注释,因此无需注册):
@WebListener
public class BackgroundJobManager implements ServletContextListener {
private ScheduledExecutorService scheduler;
@Override
public void contextInitialized(ServletContextEvent event) {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new YourParsingJob(), 0, 5, TimeUnit.HOUR);
}
@Override
public void contextDestroyed(ServletContextEvent event) {
scheduler.shutdownNow();
}
}
我的目标是创建一个简单的计时器程序。它不断更新自己,直到按下停止按钮。然而,我不确定如何停止刻度函数运行,以便定时器在按下停止按钮后保持不变。 这是我目前的代码: 停止函数的可能方法是什么? 任何帮助都将不胜感激!
我有一个类,,并用注释它。 我在该类中有两个方法: 我看到,当它应该打印它们中的内容时,它会打印出来,但当我在intelij中按一次停止按钮时,我会得到: 我需要再按一次停止按钮才能完全停止。 为什么即使到达也不关闭ExecutorService?我做错了什么? PS:这是我唯一的ExecutorService,没有其他线程是我做的。 停止按钮是intelij IDEA中play和debug按钮附
我正在使用ScheduledExecutorService并对其进行初始化(ScheduledExecutorService scheduledThreadPool=Executors.NewScheduledThreadPool(20);)这样我就不会每次都创建新线程。然后,我使用计划“executorService.schedule(new Runnable(),20,timeUnit.sec
我们有10个计划任务,配置为每20秒运行一次,带有以下注释(它们在晚上停止,因为依赖系统在早上4点重新启动): 我们有一个线程池taks调度器,配置池大小为10: 有时在一天中,其中一项任务在一两个小时内没有执行,然后继续定期执行。有没有可能其中一个任务正在阻止其他任务?我怎样才能知道情况是否如此?
我正在使用@Scheduled annotation运行cron作业。调度工作了一段时间,然后停止工作。我将给出我的代码的简化片段: 这是调度程序: 这是由调度器执行的任务 “开始代理”和“结束代理”的记录次数相同。所以,每一个日程安排都会正确地结束。 “开始任务”和“结束任务”的记录次数相同。所以,毫无疑问,“任务”并不是阻止事情。 但是过了一段时间就停止记录了。有什么问题吗? 这里,TASK_
问题内容: 我需要一些有关在PHP中启动和停止计时器的信息。我需要测量从我的.exe程序开始(我在PHP脚本中使用函数)到完成执行并显示所花费的时间(以秒为单位)之后经过的时间。 我怎样才能做到这一点? 问题答案: 您可以使用并计算差异: 这是PHP的文档:http : //php.net/manual/zh/function.microtime.php