Java计划执行器的未处理异常
我有以下问题,我想知道到底发生了什么。我使用Java每五分钟运行一次任务。它工作得很好。执行器完全改变了我用Java进行线程编程的方式 现在,我浏览了Java文档,以了解当计划任务失败并出现未处理的异常时会发生什么行为,但找不到任何信息 下一个计划任务是否仍将运行?如果存在未处理的异常,计划执行者是否停止计划任务?有人能指出关于这个简单问题的信息吗Java计划执行器的未处理异常,java,exception-handling,multithreading,executor,Java,Exception Handling,Multithreading,Executor,我有以下问题,我想知道到底发生了什么。我使用Java每五分钟运行一次任务。它工作得很好。执行器完全改变了我用Java进行线程编程的方式 现在,我浏览了Java文档,以了解当计划任务失败并出现未处理的异常时会发生什么行为,但找不到任何信息 下一个计划任务是否仍将运行?如果存在未处理的异常,计划执行者是否停止计划任务?有人能指出关于这个简单问题的信息吗 非常感谢。scheduleAtFixedRate和scheduleWithFixedDelay的Javadoc都说“如果任务的任何执行遇到异常,后续
非常感谢。scheduleAtFixedRate和
scheduleWithFixedDelay
的Javadoc都说“如果任务的任何执行遇到异常,后续执行都会被抑制。”我不认为这是非常清楚的,但是它似乎在说,如果您的run
方法抛出任何类型的异常,那么调度程序将有效地放弃该任务。通过该计划程序运行的任何其他任务都不应受到影响。测试它的实际功能应该不难
取消任务不一定是坏事。如果run方法抛出一个
RuntimeException
,那么它可能在某个地方有一个bug,并且系统的状态未知。但至少我建议在run方法中捕获RuntimeException
,并在严重时记录完整堆栈跟踪。然后,根据具体情况,您可能希望重新浏览以取消任务。但是无论哪种方式,您都需要日志记录,以便有机会找出错误所在。如果您使用的是scheduleAtFixedRate()
或scheduleAtFixedDelay()
,并且您的任务在异常情况下退出,则该任务不会被重新调度。但是,其他独立任务应按预期继续执行。(见附件)。如果您关心是否发生了这种情况,可以获取返回的ScheduledFuture
的一部分,并调用get()
方法。如果底层任务抛出异常,您将从get()
方法中抛出异常,该方法封装在ExecutionException
中。看起来API没有定义任何特定的异常处理机制。也就是说,未捕获异常只是通过线程帧弹出,并最终被记录到stderr
我发现您可以利用以下异常处理策略:
- 在任务类中定义提交给线程池的对象的处理程序李>
- 为线程池提供您自己的实现,该线程池通过或初始化默认处理程序李>
- 这个人也有同样的问题
他的解决方案是在runnable中捕获
,然后重新抛出异常
:运行时异常
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文档中没有看到这一点。快速浏览ThreadPoolExecutor(STPE在其上实现)的源代码表明,运行时异常将被捕获并通过ScheduledFuture报告回来,但它们也会导致工作线程终止。TPE将注意到此辅助线程终止,并在必要时启动新的替换线程。请参阅JDK源代码中java.util.concurrent.ThreadPoolExecutor中的runWorker()和processWorkerExit(),或Doug Lea的网站。非常感谢您的回复+1.太糟糕了,我不能接受两个答案作为“答案”。再次感谢。嘿,老兄,拉克伦赢了我一拳。。。规则就是规则奇怪..我的连续任务也停止了。我认为这些异常没有被记录。