Java Timer类:如果在其中一个任务中抛出异常,则计时器任务停止执行

时间:2012-01-05 13:08:38

标签: java timer

new Timer().scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
       System.out.println("run");
       throw new SomeRandomException();
    }
 }, 1000, 1000);

输出:run(抛出异常)

问题在于:我需要一个计时器任务来检查数据库中的特定条件(或其他)。它工作正常,但有时数据库(或其他)返回一些错误,抛出异常并且计时器崩溃,然后再没有执行单个计时器任务。是否有一些Timer实现在run()抛出异常后继续工作。

我可以

new Timer().scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        try {
            System.out.println("run");
            throw new SomeRandomException();
        } catch (Exception e) {
            System.out.println("dummy catch");
        }
    }
}, 1000, 1000);

但这似乎很蹩脚。

其他替代方法是编写我自己的Timer类实现,吞掉run方法的异常(这似乎也不对)。

2 个答案:

答案 0 :(得分:7)

使用ScheduledExecutorService。它扮演与Timer相同的角色,但修复了它的弱点(就像你遇到的那样)。

答案 1 :(得分:0)

使用ExecutorService;可以处理编译时和运行异常。

Handling exceptions from Java ExecutorService tasks
How is exception handling done in a Callable

ThreadPoolExecutor.java

final void runWorker(Worker w) {
    Thread wt = Thread.currentThread();
    Runnable task = w.firstTask;
    w.firstTask = null;
    w.unlock(); // allow interrupts
    boolean completedAbruptly = true;
    try {
        while (task != null || (task = getTask()) != null) {
            w.lock();
            // If pool is stopping, ensure thread is interrupted;
            // if not, ensure thread is not interrupted.  This
            // requires a recheck in second case to deal with
            // shutdownNow race while clearing interrupt
            if ((runStateAtLeast(ctl.get(), STOP) ||
                 (Thread.interrupted() &&
                  runStateAtLeast(ctl.get(), STOP))) &&
                !wt.isInterrupted())
                wt.interrupt();
            try {
                beforeExecute(wt, task);
                Throwable thrown = null;
                try {
                    task.run();
                } catch (RuntimeException x) {
                    thrown = x; throw x;
                } catch (Error x) {
                    thrown = x; throw x;
                } catch (Throwable x) {
                    thrown = x; throw new Error(x);
                } finally {
                    afterExecute(task, thrown);
                }
            } finally {
                task = null;
                w.completedTasks++;
                w.unlock();
            }
        }
        completedAbruptly = false;
    } finally {
        processWorkerExit(w, completedAbruptly);
    }
}