如果使用常规的try…catch来对从线程中抛出的异常进行处理,运行下面的代码会得到java.lang.RuntimeException的提示,所以可以看见使用try..catch无法捕获从线程中抛出的异常。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package Exception; public class ExceptionThread extends Thread { public void run() { throw new RuntimeException(); } public static void main(String[] args) { ExceptionThread thread = new ExceptionThread(); try { thread.start(); } catch (RuntimeException e) { System.out.println("handler the exception"); } } |
怎么处理从线程中抛出的异常呢?这里需要了解Thread类中的一个嵌套类Thread.UncaughtExceptionHandler,根据名字就可以看到是对Thread类中未捕获异常进行处理的类。
api中的解释
public static interface Thread.UncaughtExceptionHandler当 Thread 因未捕获的异常而突然终止时,调用处理程序的接口。
当某一线程因未捕获的异常而即将终止时,Java 虚拟机将使用 Thread.getUncaughtExceptionHandler() 查询该线程以获得其 UncaughtExceptionHandler 的线程,并调用处理程序的 uncaughtException 方法,将线程和异常作为参数传递。如果某一线程没有明确设置其 UncaughtExceptionHandler,则将它的 ThreadGroup 对象作为其 UncaughtExceptionHandler。如果 ThreadGroup 对象对处理异常没有什么特殊要求,那么它可以将调用转发给默认的未捕获异常处理程序。
解决方法:
运行下面代码得到的结果是Exception handler
ThreadException是一个实现Runnable接口的类,在其run方法中抛出一个异常,我们实现一个线程池,并且指定产生线程的工厂方法,在该工厂方法里面,我们每生产一个线程就调用Thread.setUncaughtExceptionHandler()为其指定异常处理handler,当线程抛出异常的时候,就会执行指定handler的uncaughtException()方法,参数由jdk自动传入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
public class CatchThreadException { public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFacotry()); exec.execute(new ThreadException()); } } class ThreadException implements Runnable { public void run() { throw new RuntimeException(); } } class MyThreadExceptionHandler implements UncaughtExceptionHandler { public void uncaughtException(Thread t, Throwable e) { System.out.println("Exception handler"); } } class HandlerThreadFacotry implements ThreadFactory { public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setUncaughtExceptionHandler(new MyThreadExceptionHandler()); return thread; } |
0 条评论