如何为线程组设置UncaughtExceptionHandler

问题描述:

假设我有5个线程属于名为“Fruits-group”的线程组。如何为线程组设置UncaughtExceptionHandler

如何一次性将UncaughtExceptionHandler分配给Fruits-group的所有线程?

我知道我们可以为所有线程定义全局UncaughtExceptionHandler。 我在找的是给整个线程组分配一个UncaughtExceptionHandler

TL; DR子类ThreadGroup并覆盖uncaughtException()方法。

一个ThreadGroupUncaughtExceptionHandler,实现uncaughtException(Thread t, Throwable e)方法:

由Java Virtual Machine调用时,该线程组中的线程因为一个未捕获的异常,并且线程没有特定的Thread.UncaughtExceptionHandler被安装。

ThreadGroupuncaughtException方法执行以下操作:

  • 如果该线程组有一个父线程组,该父的uncaughtException方法被调用两个相同的参数。
  • 否则,此方法将检查是否安装了默认的未捕获异常处理程序,如果是,则使用相同的两个参数调用其uncaughtException方法。
  • 否则,此方法确定参数Throwable是否为ThreadDeath的实例。如果是这样,没有什么特别的。否则,包含从线程的getName方法返回的线程名称以及使用ThrowableprintStackTrace方法的堆栈回溯的消息将被打印到标准错误流。

应用程序可以重写的ThreadGroup子类此方法以提供未捕获的异常的替代处理。


UPDATE

如果你想能够ThreadGroup设置UncaughtExceptionHandler,您可以创建一个委托子类:

public class ExceptionHandlingThreadGroup extends ThreadGroup { 
    private UncaughtExceptionHandler uncaughtExceptionHandler; 

    public ExceptionHandlingThreadGroup(String name) { 
     super(name); 
    } 
    public ExceptionHandlingThreadGroup(ThreadGroup parent, String name) { 
     super(parent, name); 
    } 

    public UncaughtExceptionHandler getUncaughtExceptionHandler() { 
     return this.uncaughtExceptionHandler; 
    } 
    public void setUncaughtExceptionHandler(UncaughtExceptionHandler uncaughtExceptionHandler) { 
     this.uncaughtExceptionHandler = uncaughtExceptionHandler; 
    } 

    @Override 
    public void uncaughtException(Thread t, Throwable e) { 
     if (this.uncaughtExceptionHandler != null) 
      this.uncaughtExceptionHandler.uncaughtException(t, e); 
     else 
      super.uncaughtException(t, e); 
    } 
} 

一般情况下,不过,它可能会更好,只是实施直接在子类中处理异常的逻辑,但这样,你可以使用现有的UncaughtExceptionHandler实现。

+0

'public void uncaughtException(Thread t,Throwable e)'。我知道我们必须在第二个参数中传递一个UncaughtExceptionHandler的实例,但是我们应该在第一个参数中传递哪个线程实例:'any或当前线程' –

+0

@PrakashPandey你是什么意思?你在'ThreadGroup'的子类中实现'uncaughtException()'方法,JVM会调用它。你不叫它。如果你希望你的子类使用'UncaughtExceptionHandler'并将它存储在你的子类的一个字段中,并将来自子类'uncaughtException()'实现的调用转发给给定的'UncaughtExceptionHandler',你可以传递两个参数值。 – Andreas

+0

谢谢,正是我在找的。 –