Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 导致Tomcat服务器出现问题的计时器_Java_Tomcat_Timer - Fatal编程技术网

Java 导致Tomcat服务器出现问题的计时器

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

我想在Tomcat上运行的servlet上每22分钟运行一次方法。因此,我使用以下代码:

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启动和停止计时器。

谢谢,我现在正在使用它,它似乎运行得更好。