子线程中发生了异常,如果没有任何类来接手处理的话,是会直接退出的,而不会记录任何日志。 所以,如果什么都不做的话,是会出现子线程任务既没执行成功,也没有任何日志提示的“诡异”现象的。
1、异常处理器
public class CaughtThread implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getName() + "发生异常" );
e.printStackTrace();
}
}
1.1 单个线程设置异常处理器
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
throw new IllegalArgumentException("");
}
});
thread.setUncaughtExceptionHandler(new CaughtThread());
thread.start();
}
1.2线程池设置异常处理器
public static void main(String[] args){
ExecutorService exec = Executors.newCachedThreadPool();
Thread thread = new Thread(new Runnable{
@Override
public void run()
{
Thread.currentThread().setUncaughtExceptionHandler(new CaughtThread());
throw new IllegalArgumentException("");
}
});
thread.setUncaughtExceptionHandler(new CaughtThread());
exec.execute(thread);
exec.shutdown();
}
public static void main(String[] args){
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Runnable{
@Override
public void run()
{
Thread.currentThread().setUncaughtExceptionHandler(new CaughtThread());
throw new IllegalArgumentException("");
}
});
exec.shutdown();
}
1.3全局线程设置异常处理器
生效范围:当前线程及其子线程
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new CaughtThread());
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
throw new IllegalArgumentException("");
}
});
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.execute(new Runnable() {
@Override
public void run() {
throw new IllegalArgumentException("");
}
});
thread.start();
}
2 Future.get捕获异常
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
Future<?> submit = executorService.submit(new Runnable() {
@Override
public void run() {
throw new IllegalArgumentException("");
}
});
Object o = null;
try {
o = submit.get();
} catch (ExecutionException | InterruptedException e) {
System.out.println("2");
e.printStackTrace();
}
}
参考资料:
Java子线程中的异常处理(通用) - 星朝 - 博客园 (cnblogs.com)
为线程池中的每个线程设置UncaughtExceptionHandler_对线程池(包括scheduledthreadpoolexecutor)中的线程执行setuncaug-CSDN博客