这是我的java代码。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
class ExceptionThread2 implements Runnable {
@Override
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 {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("caught " + e);
}
}
class HandlerThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
System.out.println(this + " 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());
//exec.shutdown();
}
}
结果:
com.concurrent.example.HandlerThreadFactory@7f31245a creating new Thread
created Thread[Thread-0,5,main]
eh = com.concurrent.example.MyUncaughtExceptionHandler@6d6f6e28
run() by Thread[Thread-0,5,main]
eh = com.concurrent.example.MyUncaughtExceptionHandler@6d6f6e28
com.concurrent.example.HandlerThreadFactory@7f31245a creating new Thread
created Thread[Thread-1,5,main]
eh = com.concurrent.example.MyUncaughtExceptionHandler@2870fdbb
caught java.lang.RuntimeException
当我取消注释//exec.shutdown()
时,结果会有所不同。只创建一个线程。
com.concurrent.example.HandlerThreadFactory@7f31245a creating new Thread
created Thread[Thread-0,5,main]
eh = com.concurrent.example.MyUncaughtExceptionHandler@6d6f6e28
run() by Thread[Thread-0,5,main]
eh = com.concurrent.example.MyUncaughtExceptionHandler@6d6f6e28
caught java.lang.RuntimeException
为什么?
答案 0 :(得分:3)
你的runnable崩溃了它的线程。因此,池将用新的线程替换该线程(对于您可能提交的下一个任务)。
如果池已经关闭,它将不会这样做。
答案 1 :(得分:1)
当你这样做时:
exec.execute(new ExceptionThread2());
创建工作线程并执行您的任务。
但它完全异常并在抛出异常后死亡。
在这种情况下,线程池创建另一个工作者来替换死者,因此您会看到两条created
消息但只有一条run()
消息
以下是执行任务的runWorker
:
* 1. We may start out with an initial task, in which case we
* don't need to get the first one. Otherwise, as long as pool is
* running, we get tasks from getTask. If it returns null then the
* worker exits due to changed pool state or configuration
* parameters. Other exits result from exception throws in
* external code, in which case completedAbruptly holds, which
* usually leads processWorkerExit to replace this thread.
final void runWorker(Worker w)
- 其他退出导致异常抛出 外部代码,在这种情况下完成突然持有,其中 通常会引导 processWorkerExit来替换此线程