import java.util.concurrent.*;
class ExceptionThread2 implements Runnable {
public 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 {
public void uncaughtException(Thread t, Throwable e) {
System.out.println("caught " + e);
}
}
class HandlerThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
System.out.println("Begin creating new Thread");
Thread t = new Thread(r);
System.out.println("created " + t);
t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
System.out.println("eh = " + t.getUncaughtExceptionHandler());
return t;
}
}
public class CaptureUncaughtException {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
exec.execute(new ExceptionThread2());
}
} /*
* Output: (90% match) HandlerThreadFactory@de6ced creating new Thread created
* Thread[Thread-0,5,main] eh = MyUncaughtExceptionHandler@1fb8ee3 run() by
* Thread[Thread-0,5,main] eh = MyUncaughtExceptionHandler@1fb8ee3 caught
* java.lang.RuntimeException
*/// :~
1、java编程思想第21章-在捕获异常小节中有个例子如上,讲的是怎样捕获线程中出现的异常,在书中给出的示例中可以看出,在线程抛出异常并被捕获之后,程序就停止了,也没有新建线程,但是在实际运行中并不是这样的,在java 1.8.0_171 版本下运行打印如下
Begin creating new Thread
created Thread[Thread-0,5,main]
eh = com.longwiserp.test.MyUncaughtExceptionHandler@5c647e05
run() by Thread[Thread-0,5,main]
eh = com.longwiserp.test.MyUncaughtExceptionHandler@5c647e05
Begin creating new Thread
created Thread[Thread-1,5,main]
eh = com.longwiserp.test.MyUncaughtExceptionHandler@4d37c333
caught java.lang.RuntimeException
2、可见在thread0抛出异常死掉之后,程序马上新建了一个thread1线程,如果书中的代码是正确的,那就说明java版本升级修改了这块的逻辑,通过查看newCachedThreadPool 介绍可以看到
/**
* Creates a thread pool that creates new threads as needed, but
* will reuse previously constructed threads when they are
* available. These pools will typically improve the performance
* of programs that execute many short-lived asynchronous tasks.
* Calls to {@code execute} will reuse previously constructed
* threads if available. If no existing thread is available, a new
* thread will be created and added to the pool. Threads that have
* not been used for sixty seconds are terminated and removed from
* the cache. Thus, a pool that remains idle for long enough will
* not consume any resources. Note that pools with similar
* properties but different details (for example, timeout parameters)
* may be created using {@link ThreadPoolExecutor} constructors.
*
* @return the newly created thread pool
*/
3、大概意思是,如果没有现有线程可用,就会新建一个线程放在线程池中,并且60s没有使用就删掉,在运行时候也会看到,确实新建了一个线程,并且60s后,程序就停止了。
4、如果想要和书中的输出一样,可以在Main方法中加入 exec.shutdown();