如果任务抛出 RuntimeException/Error,ScheduledExecutorService.scheduleAt* 方法是不是应该重新安排任务?
Posted
技术标签:
【中文标题】如果任务抛出 RuntimeException/Error,ScheduledExecutorService.scheduleAt* 方法是不是应该重新安排任务?【英文标题】:Should ScheduledExecutorService.scheduleAt* methods re-schedule tasks if the task throws RuntimeException/Error?如果任务抛出 RuntimeException/Error,ScheduledExecutorService.scheduleAt* 方法是否应该重新安排任务? 【发布时间】:2011-03-19 13:09:51 【问题描述】:前几天我在我的应用程序中实现了一项重要的服务,无论如何它都应该继续运行。所以我使用了以下构造:
ScheduledExecutorService ses =
Executors.newSingleThreadScheduledExecutor();
//If the thread dies, another will take over
ses.scheduleAtFixedRate(importantPeriodicTask, 1, 1, TimeUnit.NANOSECONDS);
...才发现当importantPeriodicTask 实际抛出RuntimeException 或Error 时,ScheduledExecutorService
将停止执行此任务(它们将停止被调度)。
这当然正是 javadoc 所说的:
如果任务执行 遇到异常,后续 处决被禁止。
真让我感到羞耻,但我不明白作者为什么要这样实现ScheduledExecutorService
。
当然,通常不应捕获 RuntimeException 或 Error,尤其是 Error。但实际上,特别是在 RuntimeException 的情况下,事实是它们在生产部署中很常见,我觉得几乎总是希望当特定操作失败时,应用程序本身不应该因为那个孤立的错误而失败。
确实,抑制一个周期性任务不会影响其他类型的周期性任务。但是鉴于大多数周期性任务的性质,这些任务不应该被视为“服务”,而不是孤立的任务吗?
换句话说,不应该只是importantPeriodicTask
的一个实例失败,并且任务本身会继续被重新安排吗?
【问题讨论】:
就是这样,我不确定您要寻找什么样的答案。如果您不喜欢它,则需要将任务包装在捕获异常的东西中。 @skaffman:我确实了解如何获得想要的(我的意思是我想要的)行为,但我很好奇其他人的想法.. 【参考方案1】:在我看来,目前的行为是合理的。 RuntimeExceptions 通常指的是错误。它们实际上可以出现在任务代码中的任何地方。例如,如果任务是有状态的,它可能会使其状态不一致,随后的执行将产生意想不到的行为。一般来说,我不喜欢试图从自身的错误中恢复的代码,但这是我的看法。
如果您希望更改 ScheduledExecutorService 的行为,请查看以下通用解决方案:
http://www.javaspecialists.eu/archive/Issue154.html
【讨论】:
我大体上同意,但话说回来,编写一个没有错误的软件不是也很难吗?以上是关于如果任务抛出 RuntimeException/Error,ScheduledExecutorService.scheduleAt* 方法是不是应该重新安排任务?的主要内容,如果未能解决你的问题,请参考以下文章
如果任务抛出 RuntimeException/Error,ScheduledExecutorService.scheduleAt* 方法是不是应该重新安排任务?
如何在不抛出 TaskCanceledExceptions 的情况下等待任务?