"¡Hola, amigo!

"Quiero contarte algo pequeño, pero interesante".

"Estoy escuchando. Me encantan las cosas pequeñas e interesantes".

"Bueno, sabes que cada objeto Thread tiene un método run(). Y que puedes ejecutarlo en un hilo separado usando el método start()".

"Sí, claro."

"Pero ahora imagina esta situación: inicias un subproceso para realizar algún trabajo, pero se lanza una excepción y el subproceso deja de ejecutarse porque no sabe qué hacer. ¿No necesitarías saber sobre este error de alguna manera?"

"Estoy de acuerdo. Tendría que detectar de alguna manera la excepción que ocurrió en el otro subproceso en ejecución. ¿Java incluso admite eso?"

"Me insultas. Por supuesto que sí".

"Los creadores de Java inventaron una interfaz especial llamada UncaughtExceptionHandler. Aquí se explica cómo capturar y manejar una excepción que ocurre en otro subproceso, si ese subproceso no la detecta:"

Ejemplo
public class DownloadManager
{
 public static void main(String[] args)
 {
   Thread thread = new DownloadThread();
   thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
   {
    @Override
    public void uncaughtException(Thread t, Throwable e)
    {

    }
 });

 thread.start();
}

"El objeto Thread tiene un método setUncaughtExceptionHandler especial . Debe pasarle un objeto que implemente la interfaz Thread.UncaughtExceptionHandler . Esta interfaz solo tiene un método: uncaughtException(Thread t, Throwable e) . Este es el método al que se llamará el objeto pasado si se produce una excepción no detectada en el método de ejecución".

"En mi ejemplo anterior, simplemente declaro una clase interna anónima (resaltada en rojo) que implementa la interfaz Thread. Thread.UncaughtExceptionHandler . Y anulo su método uncaughtException(Thread t, Throwable e) ".

"Como puede ver en la lista de parámetros del método, se pasarán dos argumentos: una referencia al objeto Thread donde ocurrió la excepción, y la excepción en sí, pasada como Throwable e".

"Bueno, ¿por qué necesito la variable Thread t? ¿No sabemos ya en qué Thread estamos poniendo un objeto Thread.UncaughtExceptionHandler ?"

"Hicieron esto para que pueda escribir un controlador universal para estas situaciones. Es decir, puede crear un solo objeto y pasarlo a docenas de subprocesos diferentes. Luego, el método uncaughtException(Thread t, Throwable e) siempre le brinda una referencia al Subproceso objeto donde se produjo la excepción".

"Además, puedes crear docenas de subprocesos, por ejemplo, en un bucle para realizar tareas específicas. En general, esta referencia al objeto Subproceso no será superflua. Te lo prometo".

"Te creo. Nunca te has equivocado".