Java 计划执行器未处理的异常
我有以下问题,我想知道到底发生了什么。我正在使用Java的 ScheduledExecutorService每五分钟运行一次任务。它运作得很好。执行器彻底改变了我在 Java 中进行线程编程的方式。
现在,我浏览了 Java 文档,了解计划任务因未处理的异常而失败时的行为信息,但找不到任何内容。
下一个计划任务还继续执行吗?如果出现未处理的异常,调度执行器会停止调度任务吗?任何人都可以指出有关这个简单问题的信息吗?
多谢。
I have the following issue and I would like to know what exactly happens. I am using Java's ScheduledExecutorService to run a task every five minutes. It works very well. Executors completely changed the way I do thread programming in Java.
Now, I browsed Java Doc for information about what would be the behavior in case the scheduled task fails with an unhandled exception, but couldn't find anything.
Is the next scheduled task still going to run? If there is an unhandled exception, the scheduled executor stops scheduling task? Can anyone point to information regarding this simple issue?
Thanks a lot.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
scheduleAtFixedRate
和scheduleWithFixedDelay
的 Javadoc 均表示“如果任务的任何执行遇到异常,则后续执行将被抑制”。我觉得这不是很清楚,但似乎是在说,如果您的 run 方法抛出任何类型的异常,那么调度程序将有效地放弃该任务。通过该调度程序运行的任何其他任务不应受到影响。测试它实际做了什么应该不难……取消任务不一定是坏事。如果 run 方法抛出
RuntimeException
,则可能是某个地方出现了错误,并且系统的状态未知。但至少我建议在 run 方法中捕获 RuntimeException,并在 SEVERE 处记录完整的堆栈跟踪。然后,您可能需要重新抛出以取消任务,具体取决于具体情况。但无论哪种方式,您都需要日志记录才能有机会找出问题所在。The Javadoc of both
scheduleAtFixedRate
andscheduleWithFixedDelay
says "If any execution of the task encounters an exception, subsequent executions are suppressed." I don't find that to be exactly crystal clear, but it seems to be saying that if yourrun
method throws any kind of exception, then the scheduler will effectively drop that task. Any other tasks running via that scheduler should not be affected. It shouldn't be hard to test what it actually does...Cancellation of the task may not necessarily be a bad thing. If the run method throws a
RuntimeException
, it's probably got a bug somewhere, and the state of the system is unknown. But at minimum I would advise catchingRuntimeException
in your run method, and logging the full stack trace at SEVERE. You may want to then rethrow to cancel the task, depending on the circumstances. But either way you'll need the logging to have a fighting chance of working out what went wrong.如果您使用
scheduleAtFixedRate()
或scheduleAtFixedDelay()
,并且您的任务因异常而退出,则该任务将不会被重新安排。但是,其他独立任务应继续按预期执行。 (参见API 文档)。如果您担心这种情况发生,您可以抓住返回的ScheduledFuture
并调用get()
方法。如果底层任务抛出异常,您将把它从get()
方法中抛出,并封装在ExecutionException
中。If you are using
scheduleAtFixedRate()
orscheduleAtFixedDelay()
, and your task bails out with an exception, that task will not be rescheduled. However, other independent tasks should continue to execute as expected. (See API Docs). If you care that this has happened, you can grab ahold of theScheduledFuture
that is returned and call theget()
method. If the underlying task tosses an exception, you'll get it thrown out of theget()
method, wrapped in anExecutionException
.这个人也有同样的问题。
http://code.nomad-labs.com /2011/12/09/mother-fk-the-scheduledexecutorservice/
他的解决方案是在 runnable 中捕获
Exception
并重新抛出RuntimeException
:This man had the same problem.
http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/
His solution is to catch
Exception
inside the runnable and re throw anRuntimeException
:看起来API没有定义任何特定的异常处理机制。即未捕获的异常只是通过线程框架弹出并最终被记录到 stderr。
我发现您可以利用以下异常处理策略:
It looks like the API doesn't define any specific exception handling mechanism. I.e. uncaught exception just pops through the thread frames and eventually is being logged to stderr.
I see that you can exploit the following exception handling strategies: