У меня есть основной класс Java, в классе я запускаю новый поток, в основном он ожидает, пока поток не умрет. В какой-то момент я выдаю исключение во время выполнения из потока, но я не могу перехватить исключение, выданное из потока в основном классе.
Это потому, что исключения являются локальными для потока, и ваш основной поток фактически не видит run метод. Я предлагаю вам прочитать больше о том, как работает потоковая обработка, но чтобы быстро подвести итог: ваш вызов start запускает другой поток, совершенно не связанный с вашим основным потоком. Вызов join просто ожидает, пока это будет выполнено. Исключение, которое генерируется в потоке и никогда не перехватывается, завершает его, вот почему join возвращается в ваш основной поток, но само исключение теряется.
Если вы хотите быть в курсе этих неперехваченных исключений, вы можете попробовать это:
вам не нужно передавать исключение из одного потока в другой.
если вы хотите обработать исключение, просто сделайте это в потоке, который его выдал.
в этом примере вашему основному потоку не нужно ждать от фонового потока, что на самом деле означает, что вам вообще не нужен фоновый поток.
Однако давайте предположим, что вам действительно нужно обработать исключение из другого дочернего потока. Я бы использовал ExecutorService, подобный этому:
ExecutorServiceexecutor= Executors.newSingleThreadExecutor(); Future<Void> future = executor.submit(newCallable<Void>() { @Override public Void call()throws Exception { System.out.println("** Started"); Thread.sleep(2000); thrownewIllegalStateException("exception from thread"); } }); try { future.get(); // raises ExecutionException for any uncaught exception in child } catch (ExecutionException e) { System.out.println("** RuntimeException from thread "); e.getCause().printStackTrace(System.out); } executor.shutdown(); System.out.println("** Main stopped");
С принтами
** Started ** RuntimeException from thread java.lang.IllegalStateException: exception from thread at Main$1.call(Main.java:11) at Main$1.call(Main.java:6) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) ** Main stopped