Java计划执行程序的未处理exception
我有以下问题,我想知道究竟发生了什么。 我使用Java的ScheduledExecutorService每五分钟运行一次任务。 它工作得很好。 执行者彻底改变了我在Java中进行线程编程的方式。
现在,我浏览了Java Doc,以获取有关在计划任务因未处理的exception而失败但无法找到任何内容时会出现什么行为的信息。
下一个计划任务是否仍在运行? 如果存在未处理的exception,则计划的执行程序会停止计划任务吗? 有人能指出有关这个简单问题的信息吗?
非常感谢。
scheduleAtFixedRate
和scheduleWithFixedDelay
的Javadoc表示“如果任务的任何执行遇到exception,则后续执行被抑制。” 我没有发现它完全清晰,但似乎是说如果你的run
方法抛出任何类型的exception,那么调度程序将有效地放弃该任务。 通过该调度程序运行的任何其他任务都不应受到影响。 不应该很难测试它实际上做了什么……
取消任务可能不一定是件坏事。 如果run方法抛出RuntimeException
,它可能在某处出现了错误,系统状态未知。 但至少我建议在run方法中捕获RuntimeException
,并在SEVERE上记录完整的堆栈跟踪。 您可能希望根据具体情况重新取消取消任务。 但无论哪种方式,你都需要记录,以便有机会找出问题所在。
如果您正在使用scheduleAtFixedRate()
或scheduleAtFixedDelay()
,并且您的任务因exception而退出,则不会重新安排该任务。 但是,其他独立任务应继续按预期执行。 (请参阅API文档 )。 如果你担心这种情况发生了,你可以抓住返回的ScheduledFuture
,并调用get()
方法。 如果底层任务抛出一个exception,你将把它抛出get()
方法,包装在ExecutionException
。
这个人有同样的问题。
http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/
他的解决方案是在runnable中捕获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); }
看起来API没有定义任何特定的exception处理机制。 即未捕获的exception只是弹出线程帧并最终被记录到stderr。
我看到你可以利用以下exception处理策略:
- 在任务的类中定义处理程序,将对象提交给线程池;
- 为线程池提供自己的ThreadFactory实现,通过setUncaughtExceptionHandler()或ThreadGroup的uncaughtException()初始化默认处理程序;