В общем, решал тут задачу на UncaughtExceptionHandler и немного не могу понять. Есть код :
public static Thread.UncaughtExceptionHandler handler = new OurUncaughtExceptionHandler();

   public static void main(String[] args) {
       TestedThread commonThread = new TestedThread(handler);
       commonThread.interrupt();

       Thread threadA = new Thread(commonThread, "Нить 1");
       Thread threadB = new Thread(commonThread, "Нить 2");

       threadA.start();
       threadB.start();

       threadA.interrupt();
       threadB.interrupt();
   }

public static class OurUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
       @Override
       public void uncaughtException(Thread t, Throwable e) {
           System.out.println(t.getName() + ": " + e.getMessage());
       }
   }
И есть конструктор :
public static class TestedThread extends Thread {
        public TestedThread(Thread.UncaughtExceptionHandler handler) {
            setUncaughtExceptionHandler(handler);
            start();
        }

        public void run() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                throw new RuntimeException("My exception message");
            }
        }
    }
Насколько я понял, при передаче объекта Thread в новый объект Thread в виде параметра. У нас произойдет расширение до Runnable и будет учитываться только переопределенный метод run(). Окей, так оно и работает, ибо во время исключений программа не учитывает конструктор TestedThread и не обрабатывает исключение методом setUncaughtExceptionHandler(handler);. То есть, нам нужно напрямую у новых объектов(нитей) вызвать метод. Логично! Однако, если мы засунем в конструктор TestedThread метод Thread.setDefaultUncaughtExceptionHandler(handler):
public static class TestedThread extends Thread {
        public TestedThread(Thread.UncaughtExceptionHandler handler) {
            start();
            Thread.setDefaultUncaughtExceptionHandler(handler);
        }
то по логике, ничего не должно измениться. Ведь это все еще конструктор. Однако же нет, в этом случае, по какой-то причине, он ловит эксепшены threadA и threadB. Хммм, блин, пока писал это полотно, по ходу понял, но это не точно. Получается, при использовании Thread.setDefaultUncaughtExceptionHandler(handler);, во время пока потоки threadA и threadB работают, работает и поток commonThread и он же и ловит эти исключения. Хотя, нет, попробовал заинтераптить его сразу после создания и перед созданием новых потоков:
TestedThread commonThread = new TestedThread(handler);
       commonThread.interrupt();

       Thread threadA = new Thread(commonThread, "Нить 1");
       Thread threadB = new Thread(commonThread, "Нить 2");
и выдало:
Thread-0: My exception message
Нить 2: My exception message
Нить 1: My exception message
То есть метод продолжает работать даже после остановки commonThread, если он конечно остановился 😵