Предположим, что поток запускается из основного метода. Что произойдет, если исключение выбрано в потоке, но не обработано в потоке?
Можно ли распространить исключение на основной метод?
Предположим, что поток запускается из основного метода. Что произойдет, если исключение выбрано в потоке, но не обработано в потоке?
Можно ли распространить исключение на основной метод?
Мы говорим о неконтролируемых исключениях, исходящих из метода Thread.run
.
По умолчанию вы получите это как системное сообщение:
Exception in thread "Thread-0" java.lang.RuntimeException
at Main$1.run(Main.java:11)
at java.lang.Thread.run(Thread.java:619)
Это результат printStackTrace для необработанных исключений. Чтобы справиться с этим, вы можете добавить свой собственный UncaughtExceptionHandler:
Thread t = new Thread(new Runnable(){
public void run() {
throw new RuntimeException();
}
});
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.println("exception " + e + " from thread " + t);
}
});
t.start();
Чтобы установить обработчик для всех потоков, используйте статический метод Thread.setDefaultUncaughtExceptionHandler
.
Если исключение поймано и обработано кодом, запущенным в этом потоке, тогда оно будет обработано, однако записывается логика блока catch
. Я возьму для остальной части этого ответа, что вы говорите о неперехваченных исключениях.
Неперехваченное исключение вызовет выход потока. Когда он пузырится до вершины Thread.run()
, он будет обрабатываться потоком UncaughtExceptionHandler. По умолчанию это будет просто печатать трассировку стека на консоли. Сам поток будет завершен в этот момент - он не может продолжаться в любом случае, потому что его метод run()
завершен.
Итак, если вы хотите, чтобы исключение было ререйзировано в вашем основном потоке, вы можете определить UncaughtExceptionHandler, который сделает это (это очень простой интерфейс), а затем вызовите Thread.setUncaughtExceptionHandler
на порожденный поток после его создания, ваш пользовательский обработчик исключений.
Единственная потенциально сложная часть написания обработчика - это определить, где и как именно вы собираетесь "вставить" броски в основной поток. Это не совсем очевидно, если ваш поток отключает выполнение чего-то другого и будет сильно зависеть от того, как вы разработали приложение и как выглядит его параллельная поддержка.
(Если, с другой стороны, ваш основной поток просто ждет, пока другой поток будет запущен, тогда это станет проще. Но в этом случае, возможно, ваш Основной поток должен отправить задачу на поточный ExecutorService
и блокировать на Future
, который будет обрабатывать все эти материалы для проводки/жизненного цикла для вас?)
Нет, не может. Когда вы подумаете об этом, метод main()
мог завершиться несколько дней назад.
Любое неперехваченное исключение из потока распространяется на поток UncaughtExceptionHandler
. Если он не определен, он переходит к обработчику группы потоков, если он тоже не установлен, он переходит к обработчику по умолчанию.
Если исключение не обрабатывается try {} catch (Exception e){}
, тогда оно поднимается и переключается на вызываемую функцию.
Если это отдельный автономный поток, вы не можете распространять его на объект, который не является родителем потока
Или какая-либо другая информация здесь: Как выбросить проверенное исключение из потока java?
Обычно, если вы не выполняете исключения самостоятельно, когда происходит какое-то исключение, оно завершает выполнение.
Исключение попадает на UncaughtExceptionHandler. Вы можете поймать его там, чтобы отправить его обратно в основной поток, если хотите.