Java 调度执行程序未处理的异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1660834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unhandled exceptions with Java scheduled executors
提问by Pablo Santa Cruz
I have the following issue and I would like to know what exactly happens. I am using Java's ScheduledExecutorServiceto run a task every five minutes. It works very well. Executors completely changed the way I do thread programming in Java.
我有以下问题,我想知道到底发生了什么。我使用 Java 的ScheduledExecutorService每五分钟运行一次任务。它运作良好。Executors 彻底改变了我在 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.
现在,我浏览了 Java Doc 以获取有关在计划任务因未处理的异常而失败的情况下的行为的信息,但找不到任何内容。
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.
非常感谢。
采纳答案by Lachlan
The Javadoc of both scheduleAtFixedRateand scheduleWithFixedDelaysays "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 your runmethod 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...
两者的JavadocscheduleAtFixedRate和scheduleWithFixedDelay说,“如果任务的任一执行遇到异常,就会取消后续执行。” 我觉得这不是很清楚,但似乎是说如果您的run方法抛出任何类型的异常,那么调度程序将有效地删除该任务。通过该调度程序运行的任何其他任务不应受到影响。测试它的实际作用应该不难......
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 catching RuntimeExceptionin 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.
取消任务不一定是坏事。如果 run 方法抛出 a RuntimeException,则可能是某处存在错误,并且系统状态未知。但至少我会建议捕获RuntimeException您的 run 方法,并在 SEVERE 处记录完整的堆栈跟踪。然后您可能希望重新抛出以取消任务,具体取决于具体情况。但无论哪种方式,您都需要日志记录才能有机会找出问题所在。
回答by andersoj
If you are using scheduleAtFixedRate()or scheduleAtFixedDelay(), 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 the ScheduledFuturethat is returned and call the get()method. If the underlying task tosses an exception, you'll get it thrown out of the get()method, wrapped in an ExecutionException.
如果您正在使用scheduleAtFixedRate()或scheduleAtFixedDelay(),并且您的任务因异常而退出,则不会重新安排该任务。但是,其他独立任务应继续按预期执行。(请参阅API 文档)。如果您关心这是否发生,您可以抓住ScheduledFuture返回的 并调用该get()方法。如果底层任务抛出异常,您将把它从get()方法中抛出,包裹在ExecutionException.
回答by mrclrchtr
This man had the same problem.
这个人也有同样的问题。
http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/
http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/
His solution is to catch Exceptioninside the runnable and re throw an RuntimeException:
他的解决方案是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);
}
回答by denis.zhdanov
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.
看起来 API 没有定义任何特定的异常处理机制。即未捕获的异常只是通过线程帧弹出并最终被记录到标准错误。
I see that you can exploit the following exception handling strategies:
我发现您可以利用以下异常处理策略:
- define handler at the class of the task which objects are submitted to thread pool;
- provide your own ThreadFactoryimplementation to thread pool that initializes default handler via setUncaughtExceptionHandler()or ThreadGroup's uncaughtException();
- 在将对象提交给线程池的任务的类中定义处理程序;
- 向线程池提供您自己的ThreadFactory实现,该线程池通过setUncaughtExceptionHandler()或ThreadGroup 的 uncaughtException()初始化默认处理程序;

