捕获子线程中的异常
Posted duanguyuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了捕获子线程中的异常相关的知识,希望对你有一定的参考价值。
如下代码,在 main 线程中,是无法捕获子线程的异常的。
catch
子句中的代码不会被执行。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NaiveExceptionHandling {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
try {
exec.execute(() -> {
throw new RuntimeException();
});
} catch (RuntimeException e) {
System.out.println("this msg will not de printed");
}
exec.shutdown();
}
}
输出:
Exception in thread "pool-1-thread-1" java.lang.RuntimeException
at NaiveExceptionHandling.lambda$main$0(NaiveExceptionHandling.java:9)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Process finished with exit code 0
改造:
newCachedThreadPool
创建线程池时指定自定义的ThreadFactory
- 自定义的
ThreadFactory
工厂在生产线程时,为其设置UncaughtExceptionHandler
异常处理
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public class NaiveExceptionHandling {
public static void main(String[] args) {
ExecutorService exec2 = Executors.newCachedThreadPool(new HandleThreadFactory());
exec2.execute(() -> {
throw new RuntimeException();
});
exec2.shutdown();
}
}
class HandleThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
System.out.println("create thread t");
Thread t = new Thread(r);
System.out.println("set uncaughtException for t");
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("caught " + e);
}
});
return t;
}
}
输出:
create thread t
set uncaughtException for t
caught java.lang.RuntimeException
那么主线程为什么不能捕获子线程的异常呢?知乎上有如下解释:
- 因为execute方法会立即返回,所以早就运行出try块了,实际上主线程已经提前结束。
- 设计的主要初衷是线程运行是互相独立的,可以理解主线程也是一种普通的线程即可。如果线程之间异常互相干扰,那么1000个线程,一个线程挂了,其它线程跟着遭殃,这是不合理的。
ref:
- https://blog.csdn.net/wild46cat/article/details/80808555
- 《Java 编程思想(第4版)》 P672
- https://www.zhihu.com/question/67790293
以上是关于捕获子线程中的异常的主要内容,如果未能解决你的问题,请参考以下文章