线程捕获异常

来源:互联网 发布:unity3d 半条命 编辑:程序博客网 时间:2024/06/03 06:38

由于线程的本质特性,不难捕获从线程中逃逸的异常。一旦异常逃出任务的run()方法,它就会像外传播到控制台,在控制台中无法捕获,除法采取特殊的步骤

来捕获这些异常。

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadTest implements Runnable{public static void main(String[] args)  {try{ExecutorService exec =  Executors.newCachedThreadPool();exec.execute(new ThreadTest());}catch(Exception e){System.out.println(e);}}@Overridepublic void run() {throw new RuntimeException();}}


输出:

Exception in thread "pool-1-thread-1" java.lang.RuntimeExceptionat thread.ThreadTest.run(ThreadTest.java:18)at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)at java.lang.Thread.run(Unknown Source)

在控制台中并没有捕获这些异常。

为了解决这个问题,要修改Executor产生线程的方式。Thread.UncaughtExceptionHandler,允许在每个Thread对象上附着一个异常处理器。

Thread.UncaughtExceptionHandler.uncaughtException()会在线程因未捕获的异常而临近死亡时被调用。为了使用它,创建一个新类型的

ThreadFactory,它将在新创建的Thread对象上附着一个Thread.UncaughtExceptionHandler。将这个工厂传递给Excutors创建新的ExecutorService的方法

package thread;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ThreadFactory;public class CaptureUncaughtException {public static void main(String[] args) {ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());exec.execute(new ExceptionThread2());}}class ExceptionThread2 implements Runnable{@Overridepublic void run() {Thread t = Thread.currentThread();System.out.println("run() by"+t);System.out.println("eh="+t.getUncaughtExceptionHandler());throw new RuntimeException();}}//异常处理器class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{@Overridepublic void uncaughtException(Thread t, Throwable e) {System.out.println("caught "+e);}}class HandlerThreadFactory implements ThreadFactory{@Overridepublic Thread newThread(Runnable r) {System.out.println(this+" creating new Thread");Thread t = new Thread(r);System.out.println("created "+t);//给创建的线程设置处理器t.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());return t;}}



输出:

thread.HandlerThreadFactory@7852e922 creating new Threadcreated Thread[Thread-0,5,main]run() byThread[Thread-0,5,main]eh=java.lang.ThreadGroup[name=main,maxpri=10]thread.HandlerThreadFactory@7852e922 creating new Threadcreated Thread[Thread-1,5,main]caught java.lang.RuntimeException

可以看出ThreadFacotory创建了另一个线程来捕获异常

在程序中添加了额外的跟踪机制,用来验证工厂创建的线程会传递给UncaughtExceptionHandler,然后通过uncaughtException()来捕获。

Thread.setDefaultUncaughtExceptionHandler();//创建默认的异常捕获处理器

这个处理器只有在不存在线程专有的未捕获异常处理器的情况下才会被调用。系统会检查专有版本,如果没有发现,则检查线程组是否有专有的uncaughtException()方法,

如果也没有,再调用defaultUncaughtExceptionHandler

0 0
原创粉丝点击