2009-11-02 23 views
25

我有以下问题,我想知道究竟发生了什么。我正在使用Java的ScheduledExecutorService每五分钟运行一次任务。它工作得很好。执行器完全改变了我在Java中进行线程编程的方式。Java预定执行程序未处理的异常

现在,我浏览了Java Doc以获取有关如果计划的任务失败并出现未处理的异常而无法找到任何内容时的行为的信息。

下一个计划任务是否仍将运行?如果有未处理的异常,调度执行程序停止调度任务?任何人都可以指出有关这个简单问题的信息吗

非常感谢。

回答

24

scheduleAtFixedRatescheduleWithFixedDelay的Javadoc说:“如果任务的任何执行遇到异常,则后续执行被禁止。”我没有发现这一点完全清楚,但它似乎是说如果你的方法抛出任何异常,那么调度器将会有效地放弃这个任务。通过该调度程序运行的其他任务不应受到影响。它不应该很难测试它实际上做什么...

取消任务可能不一定是件坏事。如果run方法抛出一个RuntimeException,它可能在某处出现了错误,并且系统的状态是未知的。但至少我会建议在您的运行方法中捕获RuntimeException,并在SEVERE处记录完整的堆栈跟踪。您可能需要根据具体情况重新推出取消任务。但无论哪种方式,您都需要记录才能有机会解决出了什么问题。

+0

非常感谢您的答复。我在API Doc中没有看到。 – 2009-11-02 12:52:20

+5

快速浏览ThreadPoolExecutor的源代码(在STPE的实现上),表明RuntimeExceptions将被整齐地捕获并通过ScheduledFuture报告回来,但它们也会导致工作线程终止。如果需要,TPE会注意到这个工作线程终止并启动一个新的替换。请参阅JDK源代码或Doug Lea网站上的java.util.concurrent.ThreadPoolExecutor中的runWorker()和processWorkerExit()。 – andersoj 2009-11-02 12:56:38

11

如果您使用的是scheduleAtFixedRate()scheduleAtFixedDelay(),并且您的任务以异常保留,则该任务不会被重新计划。但是,其他独立任务应该继续按预期执行。 (见API Docs)。如果您注意发生了这种情况,您可以抓取返回的ScheduledFuture,并调用get()方法。如果潜在任务抛出异常,则会从get()方法中抛出,并包装在ExecutionException中。

+0

非常感谢回复。 +1。太糟糕了,我不能接受两个答案作为“答案”。再次感谢。 – 2009-11-02 12:52:58

+0

嘿,伙计,拉克兰打败了我......规则就是规则。 ;-) – andersoj 2009-11-02 12:57:54

+0

奇怪..我的连续任务也停止了。 – 2014-04-25 07:41:39

-3

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

我看到,你可以利用下面的异常处理策略:

+0

我不认为这些例外记录。 – 2011-12-30 10:29:55

1

这个人有同样的问题。

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

他的解决办法是捕捉Exception可运行的内部和重新抛出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); 
}