34

我有以下问题,我想知道到底发生了什么。我使用 Java 的ScheduledExecutorService每五分钟运行一次任务。它工作得很好。Executors 彻底改变了我在 Java 中进行线程编程的方式。

现在,我浏览了 Java Doc 以获取有关在计划任务因未处理的异常而失败但找不到任何东西的情况下的行为的信息。

下一个计划任务还会运行吗?如果有未处理的异常,被调度的executor停止调度任务?谁能指出有关这个简单问题的信息?

非常感谢。

4

4 回答 4

34

scheduleAtFixedRate两者的JavadocscheduleWithFixedDelay都说“如果任务的任何执行遇到异常,则禁止后续执行。” 我觉得这不是很清楚,但似乎是说如果您的run方法抛出任何类型的异常,那么调度程序将有效地放弃该任务。通过该调度程序运行的任何其他任务不应受到影响。测试它的实际作用应该不难......

取消任务未必是件坏事。如果 run 方法抛出 a RuntimeException,则可能是某个地方出现了错误,并且系统的状态是未知的。但至少我会建议RuntimeException在你的运行方法中捕获,并在 SEVERE 记录完整的堆栈跟踪。您可能需要重新抛出以取消任务,具体取决于具体情况。但无论哪种方式,您都需要伐木才能有机会找出问题所在。

于 2009-11-02T12:11:40.493 回答
13

如果您正在使用scheduleAtFixedRate()or scheduleAtFixedDelay(),并且您的任务因异常而退出,则该任务将不会被重新安排。但是,其他独立任务应继续按预期执行。(请参阅API 文档)。如果您关心这是否发生,您可以获取ScheduledFuture返回的内容并调用该get()方法。如果底层任务抛出异常,您会将其从get()方法中抛出,并以ExecutionException.

于 2009-11-02T12:13:31.910 回答
3

这个人也有同样的问题。

http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/

他的解决方案是Exception在 runnable 内捕获并重新抛出RuntimeException

try {
       theRunnable.run();
    } catch (Exception e) {
       // LOG IT HERE!!!
       System.err.println("error in executing: " + theRunnable + ". It will no longer be run!");
       e.printStackTrace();

       // and re throw it so that the Executor also gets this error so that it can do what it would
       // usually do
       throw new RuntimeException(e);
}
于 2014-03-05T10:41:00.143 回答
-2

看起来 API 没有定义任何特定的异常处理机制。即未捕获的异常只是通过线程帧弹出并最终被记录到stderr。

我看到您可以利用以下异常处理策略:

于 2009-11-02T12:14:00.443 回答