Java 导致Tomcat服务器出现问题的计时器
我想在Tomcat上运行的servlet上每22分钟运行一次方法。因此,我使用以下代码:Java 导致Tomcat服务器出现问题的计时器,java,tomcat,timer,Java,Tomcat,Timer,我想在Tomcat上运行的servlet上每22分钟运行一次方法。因此,我使用以下代码: Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { try { update(); } catch (SQLException | NamingException | InterruptedExceptio
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
update();
} catch (SQLException | NamingException | InterruptedException e1) {
e1.printStackTrace();
}
}
}, 22 * 60 * 1000, 22 * 60 * 1000);
我有一种感觉,这是一种糟糕的方式,因为我总是在计时器方面出错,每当我上传一个新版本的servlet时,我认为它不会停止前一个计时器。然后我得到数据库连接警告。如果我重新设定一切,重新开始,一切都会好起来
javax.naming.NameNotFoundException: Name comp is not bound in this Context
at org.apache.naming.NamingContext.lookup(NamingContext.java:770)
at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:152)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at my.app.database.DatabaseManager.connect(DatabaseManager.java:44)
at my.app.database.DatabaseManager.returnInfo(DatabaseManager.java:133)
at my.app.genParse.Generate.updateHistory(Generate.java:89)
at my.app.MyServer$1.run(MyServer.java:52)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
以及在重新推出新版本时:
SEVERE: The web application [/myApp] appears to have started a thread named [Timer-7] but has failed to stop it. This is very likely to create a memory leak.
有什么更好的方法来实现或避免这一点 已经讨论了使用计时器任务的替代方法。使用
ScheduledThreadpoolExecutor
类可以帮助解决上载新版本时多个线程仍在运行的问题,但是我不能肯定它会。由于中讨论的各种原因,此类也优于Timer
类。您不应该在容器内真正使用定时器-定时器产生/重用容器外管理的线程,这可能会导致问题
还要注意的是,由于计时器使用单个线程,如果一个实例花费的时间太长,则其他实例的准确性可能会受到影响
最后,如果计时器
抛出未检查的异常,则计时器
线程终止
由于这些(以及其他)原因,它在很大程度上已经失宠了——ScheduledThreadPoolExecutor是一个更好的选择
不过,容器中由用户管理的线程也可能很棘手。JSR-236(JavaEE平台的并发实用程序)将在将来提供这样做的机制,但目前最好避免这种机制
您可以尝试通过cron安排可重复的任务,也许这样可以定期调用专用servlet(或类似的服务)。当web应用程序启动和停止时,使用ServletContextListener启动和停止计时器。谢谢,我现在正在使用它,它似乎运行得更好。