在新的执行线程中使用catch throwable或catch Exception

时间:2011-04-19 19:30:11

标签: java try-catch

我需要在启动新线程时找到try-catch的最佳实践。

就个人而言,我更喜欢选项2。

哪种选择是最佳做法?是否有任何因素可能使这两种选择在某些情况下成为最佳做法而不是其他情况?

选项1

public void run(){
  try{
     //do something
   }catch(Exception e){
     // log 
   }
}

选项2

public void run(){
  try{
     //do something
   }catch(Throwable t){
     // log
    }
}

编辑:假设您正在编写必须满足严格代码审查的代码。 编辑2:我知道上述两个选项之间的区别。我只是对其他人所看到的“100%正确”感到好奇。

4 个答案:

答案 0 :(得分:4)

在简单记录出错的根异常处理程序中,区分ErrorException是没有意义的,因此捕获Throwable是完全可以接受的。

如果您正在编写一些重试逻辑,我会抓住Exception,因为在Error之后确实没有重试点 - 事实上,它可能是危险的,因为错误被抛出在非异常安全的代码中,因此可能使系统处于不一致状态。

因此,它取决于您正在编写的异常处理程序。

答案 1 :(得分:3)

我会在线程上使用setDefaultUncaughtExceptionHandler(...)来捕获runnable无法正确处理的内容,但是当涉及到runnable本身时,它实际上取决于它必须实现什么并合理地预期考虑合理执行上下文。

另一方面,创建一个单独的线程来执行runnable并不是一个好的策略恕我直言,FutureTask更好地处理这些问题。

答案 2 :(得分:1)

永远不建议捕获Throwable,因为这包括无法处理或避免的错误,例如内存不足错误等。因此,捕获Exception而不是捕获Throwable通常要好得多。有时它是不可避免的,例如在调用invoke方法或其他反射方法时。

答案 3 :(得分:1)

您要问的是故障障碍的概念,实施故障的正确方法应该是您正在进行的项目或您正在使用的框架所定义的标准。

如果您的项目有记录所有异常/错误的策略,并且不允许任何打印到标准错误,您可能需要考虑使用UncaughtExceptionHandler

一般的最佳做法是仅捕获RuntimeException的实例。

public void run(){
  try{
     //do something
   }catch(RuntimeException e){
     // log 
   }
}

捕获Exception过于笼统,因为Java语言需要程序来处理已检查的异常。通过在您的故障障碍中捕获甚至检查过的异常,您允许//do something块中的代码是草率的而不处理已检查的异常。

捕获ErrorThrowable通常也被认为是一种不好的做法,因为错误通常表明JVM处于无法继续正常运行的状态。

这是一篇关于异常处理的好文章(有些相关):http://www.oracle.com/technetwork/articles/entarch/effective-exceptions-092345.html