Куда выбрасывает exception threadа

Alexander Belov

Есть код который запускает поток который в свою очередь запускает еще один поток. во внутреннем потоке выбрасываю exception и этот exception пишется в консоль, перехватить его не получается. В чем дело, я всегда думал что exception в потоках это ни как не влияет на главный поток. Я считал что только через future можно получить exception в главном потоке.

public static void main(String[] args) throws InterruptedException {
    try {
        Thread thread = new Thread(() -> {
            Thread thread1 = new Thread(() -> {
                throw new RuntimeException();
            });
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                thread1.start();
            } catch (Exception e) {
                System.out.println("1" + e.getMessage());
            }
        });
        try {
            thread.start();
        } catch (Exception e) {
            System.out.println("2" + e.getMessage());
        }
        System.out.println(1);
        Thread.sleep(1000);
        System.out.println(2);
    } catch (Exception e) {
        System.out.println("3" + e.getMessage());
    }
}

А логах вижу такое

1
 Exception in thread "Thread-1" java.lang.RuntimeException
at 
test.lambda$ 
null$0(Test.java:53)
at java.lang.Thread.run(Thread.java:748)
2
1 ответ

Alexander Belov

Так ваш Exception и не вляет на главный поток. Сами посмотрите на вывод. Сначала идет из главного потока

1

Затем второй поток бросает исключание, которое никак не перехватывается (поэтому то вы и видите эту запись в консоли):

Exception in thread "Thread-1" java.lang.RuntimeException
at 
test.lambda$ 
null$0(Test.java:53)
at java.lang.Thread.run(Thread.java:748)

А main продолжает работать как ни в чем не бывало:

2

А перехватываеть его надо не в main, а в Runnable, то есть тут:

Thread thread1 = new Thread(() -> {
     throw new RuntimeException();
});

И только так:

Thread thread1 = new Thread(() -> {
     try {
          throw new RuntimeException();
     } catch(...) {}
});

Потому что нигде больше вы его не сможете перехватить.

licensed under cc by-sa 3.0 with attribution.