"Olá, Amigo!

"Eu quero te contar sobre algo pequeno, mas interessante."

"Estou ouvindo. Adoro coisas pequenas e interessantes."

"Bem, você sabe que todo objeto Thread tem um método run(). E que você pode executá-lo em um thread separado usando o método start()."

"Sim claro."

"Mas agora imagine esta situação: você inicia um thread para executar algum trabalho, mas uma exceção é lançada e o thread para de executar porque não sabe o que fazer. Você não precisaria saber sobre esse erro de alguma forma?"

"Concordo. Eu precisaria capturar de alguma forma a exceção que ocorreu no outro thread em execução. O Java suporta isso?"

"Você me insulta. Claro que sim."

"Os criadores de Java inventaram uma interface especial chamada UncaughtExceptionHandler. Veja como capturar e manipular uma exceção que ocorre em outro thread, se esse thread não capturá-la:"

Exemplo
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();
}

"O objeto Thread tem um método setUncaughtExceptionHandler especial . Você precisa passar para ele um objeto que implemente a interface Thread.UncaughtExceptionHandler . Essa interface tem apenas um método: uncaughtException(Thread t, Throwable e) . Esse é o método que será chamado em o objeto passado se ocorrer uma exceção não capturada no método run."

"No meu exemplo acima, eu simplesmente declaro uma classe interna anônima (destacada em vermelho) que implementa a interface Thread. Thread.UncaughtExceptionHandler . E eu sobrescrevo seu método uncaughtException(Thread t, Throwable e) ."

"Como você pode ver na lista de parâmetros do método, dois argumentos serão passados: uma referência ao objeto Thread onde ocorreu a exceção e a própria exceção, passada como Throwable e."

"Bem, por que preciso da variável Thread t? Já não sabemos em qual Thread estamos colocando um objeto Thread.UncaughtExceptionHandler ?"

"Eles fizeram isso para que você possa escrever um manipulador universal para essas situações, ou seja, você pode criar um único objeto e passá-lo para dezenas de threads diferentes. Então, o método uncaughtException(Thread t, Throwable e) sempre fornece uma referência ao Objeto de thread onde ocorreu a exceção."

"Além disso, você pode criar dezenas de threads, por exemplo, em um loop para executar tarefas específicas. Em geral, essa referência ao objeto Thread não será supérflua. Eu prometo a você."

"Eu acredito em você. Você nunca esteve errado."