2

前几天我在我的应用程序中实现了一项重要的服务,无论如何它都应该继续运行。所以我使用了以下构造:

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失败,并且任务本身继续被重新安排吗?

4

1 回答 1

3

在我看来,目前的行为是合理的。RuntimeExceptions 通常指的是错误。它们实际上可以出现在任务代码中的任何地方。例如,如果任务是有状态的,它可能会使其状态不一致,随后的执行将产生意想不到的行为。一般来说,我不喜欢试图从自己的错误中恢复的代码,但这是我的看法。

如果您希望更改 ScheduledExecutorService 的行为,请查看以下通用解决方案:

http://www.javaspecialists.eu/archive/Issue154.html

于 2010-07-22T12:58:53.970 回答