在调度程序中捕获Throwable是一个好习惯吗?

时间:2019-07-18 09:05:38

标签: java spring scheduled-tasks stack-overflow

我宁愿说快速失败并且不赶上Throwable是一个好习惯。但是,如果在诸如StackOverflowError之类的请求处理器中发生未处理的异常,则该任务可能会停止。听起来并不总是那么好。我宁愿一遍又一遍地抓住StackOverflowError,但是可能会处理一些任务。什么是好的做法?

3 个答案:

答案 0 :(得分:1)

这来自Error的javadoc:

  

错误是Throwable的子类,它指示严重的问题,而合理的应用程序不应尝试捕获这些问题。

我通常遵循此规则,以避免抑制应该修复的实际意外错误。
您提到StackoverflowError,如果您遇到这种错误,则可能是您的算法有问题,应该对代码进行优化。

如果您知道可能会引发特定错误,并且对此还可以,则可以捕获该错误。 但是,如果您不希望出现这种情况,最好尽快发出警报并加以处理。

答案 1 :(得分:1)

关于捕获Error因此没有Throwable并没有“好的实践”或“最佳实践” 1

  • 一方面,JVM在某些情况下可以从某些Error成功恢复。例如,如果您在不与其他线程(直接或间接)交互的单个线程上运行“任务”,则该线程可以安全地从StackOverflowError中恢复,并且可能从 1 a OutOfMemoryError

  • 另一方面,许多Error子类表明应用程序或JVM处于无法恢复或不可行的状态:

    • 类加载或初始化Error意味着某些类将处于不可用状态。依赖该类的应用程序将无法继续。
    • 如果使用通知/等待或更高级别同步构造的应用程序在一个线程上遇到OutOfMemoryError错误(例如),则有可能让其他线程等待可能永远不会到达的通知,等等。

我的建议是,注意javadoc中对Error的暗示建议,而不是抓住并尝试从Error或其子类中恢复。如果您尝试恢复,请考虑应用程序可能“楔入”的可能性。


1-实际上,根本没有“最佳实践”。参见https://www.satisfice.com/blog/archives/5164

2-这取决于根本原因。如果根本原因是代码库中其他地方的内存泄漏,那么恢复是个坏主意。 OOME可能会随着频率的增加而复发。

答案 2 :(得分:0)

好的做法是捕获计划的作业,编写有关异常,指标的日志,并(重新安排)重新计划。

此外,有时您的线程将被停止/销毁(Hello Spring Scheduler),导致您收到某种异常,这对您的工作而言并不重要...

相关问题