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

Java 在新的执行线程中使用catch throwable或catch Exception,java,try-catch,Java,Try Catch,我需要找出在启动新线程时尝试捕获的最佳实践 就我个人而言,我更喜欢选择2 哪个选项是最佳实践?在某些情况下,是否有任何因素可以使任一选项成为最佳实践,而在其他情况下则不是 选择1 public void run(){ try{ //do something }catch(Exception e){ // log } } 选择2 public void run(){ try{ //do something }catch(Throwable

我需要找出在启动新线程时尝试捕获的最佳实践

就我个人而言,我更喜欢选择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%正确的”。

捕获可丢弃的
是不明智的,因为这包括无法处理或避免的错误,如内存不足错误等。因此,通常最好捕获
异常
,而不要捕获
可丢弃的
。有时这是不可避免的,例如在调用invoke方法或其他反射方法时。

我会在线程上使用setDefaultUncaughtExceptionHandler(…)来捕获runnable不能正确处理的内容,但是当涉及到runnable本身时,这实际上取决于它必须实现什么,以及考虑到合理的执行环境,合理地预测


另一方面,创建一个单独的线程来执行runnable并不是一个好策略,因为IMHO可以更好地处理这些问题。

在根异常处理程序中,只记录出错的内容,区分
错误和
异常是毫无意义的,因此,捕获可丢弃的
是完全可以接受的

相反,如果您正在编写一些重试逻辑,我会捕获
异常
,因为在
错误
之后重试没有意义-事实上,这可能是危险的,因为错误是在不安全的代码中抛出的,因此可能会使系统处于不一致的状态


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

您试图询问的是故障屏障的概念,而实现故障屏障的正确方法应该是您正在工作的项目或您正在使用的框架定义的标准

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

一般的最佳实践是只捕获RuntimeException的实例

public void run(){
  try{
     //do something
   }catch(RuntimeException e){
     // log 
   }
}
捕获
异常
过于通用,因为Java语言要求程序处理已检查的异常。通过在故障屏障上捕获甚至已检查的异常,您允许
//do something
块中的代码松散,而不处理已检查的异常

捕获
Error
Throwable
通常也被认为是一种不好的做法,因为错误通常表示JVM处于无法继续有效运行的状态


下面是一篇关于异常处理的好文章:

你说的“启动新线程”是什么意思?@JVerstry new thread(myRunnableObj).start();是的,但至少throwable可以被抓到并记录。。在选项1中,如果发生java.lang.Error,线程甚至不会记录任何内容,只是在没有跟踪的情况下消失。我不希望运行引发任何类型的异常。因为启动这些线程的工作流不关心它们启动后会发生什么。我的兴趣只是在事情变坏时让生活变得更轻松。我不希望出现java.lang.Error确实发生,并且没有被记录的情况。您说过“捕获Throwable是可接受的”,那么您是否也会说“捕获异常是可接受的”?对于日志异常处理程序?不,您不想区分错误和异常,那么为什么要编写两个catch块,不必要地复制代码呢?或者更糟糕的是,用catch块记录一个异常,用线程的UncaughtExceptionHandler记录另一个异常?保持简单!很抱歉造成混淆,我之前的问题应该是:选项1和选项2对您来说是否“可接受”?否。仅捕获异常将导致错误不会被记录(或由UncaughtExceptionHandler记录到错误的位置)。为什么会有人想要这个?明白了。我更喜欢选项2。@TimBender谢谢你的链接。线程死后,“坏状态”可能会消失。为什么我们不捕捉并记录坏的状态?因为“可能”不是“确定的”,坏的状态可能会导致奇怪的错误。@meriton哦,来吧。。我以为你刚才已经同意,根据你的意见,选项2是首选的方式?@TimBender我喜欢这个主意。。但是不是使用与
catch(Throwable)
相同的方法吗?@rk2010,我个人的观点是,捕获
异常
Throwable
是错误的(很少有异常),因为它去除了一些关于检查异常的编译时安全性。如果希望捕获日志中的
错误
,我认为这很好。然而,我的偏好是包含一个单独的catch块,而不是泛化为
Throwable
。我意识到这意味着可能会为代码无法处理的每个已检查异常添加一个catch块,但至少处理每个异常的意图是明确的。要做的“正确的事情”取决于项目/框架策略。我可能是错的,也可能是错的,但UncaughtExceptionHandler的方法签名似乎表明它等同于“捕获可丢弃的对象”是的,但您不必将它放在所有可运行的对象中。如果你忘了把try/catch放在runnable里怎么办?这个处理程序意味着更少的重复代码。那么,你会说你更喜欢选项2(条件是catch throwable是使用UnCaughtExceptionHandler实现的)?@rk2010是的,我想知道我在代码中没有预料到什么。当出现完全意外的情况时,收集信息以进行调试/分析总是很好的(尤其是当应用程序崩溃时)。这是我