1

我想在 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.

有什么更好的方法来实现或避免这种情况?

4

3 回答 3

1

An alternative to using timer tasks has been discussed here. Using the ScheduledThreadpoolExecutor class MAY help with the problem of having multiple threads still running when you upload a new version however I cannot say for sure that it will. This class is also preferred over the Timer class for various reasons discussed in the javadoc.

于 2013-02-20T16:54:41.177 回答
1

You shouldnt really use a Timer within a container - Timer spawn/reuse a thread thats managed outside of the container and this can cause problems.

Note too that as Timer uses a single thread if one instance of it takes too long the others accuracy can suffer.

Finally, if a Timer throws an unchecked exception the Timer thread is terminated.

For these (and other) reasons it has largely fallen out of favour - ScheduledThreadPoolExecutor is a better choice.

Again though, user managed threads within a container can be tricky. JSR-236 (Concurrency Utilities for the Java EE platform) will provide a mechanism to do so in the future, but for now its best avoided.

You can try schedule repeatable tasks via cron perhaps that could in turn call a dedicated servlet (or similar) on a regular basis

于 2013-02-20T17:05:01.077 回答
0

Use a ServletContextListener to start and stop your Timer when the web application starts and stops.

于 2013-02-20T21:07:23.450 回答