1 线程执行程序,发生异常,通过try{}catch 捕抓异常
try{
}catch(Excecption e){
//异常处理逻辑
}
2 线程池中线程发生异常,如何处理
提出问题:
从以下三个维度来分析下线程异常后执行情况
- 线程池是否抛出异常
- 线程是否删除
- 异常线程是否影响线程池中其他线程
得到结论:
不同执行方式处理异常不一致,线程池执行线程两种方式
- pool.execute(runnable):线程池抛出异常,线程删除,不影响
- pool.sumbit(runnable):线程池不抛出异常,线程不删除,不影响
代码验证:
execute
package com.hmh.thread;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author: hmh
* @date :2024/6/18 10:12
*/
public class ThreadPoolExceptionTest {
static ThreadFactory threadFactory = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println(Thread.currentThread().getName()+" 抛出异常:" + e);
}
});
return thread;
}
};
private static ThreadPoolExecutor pool =
new ThreadPoolExecutor(
4,
8,
2,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100),
threadFactory,
new ThreadPoolExecutor.CallerRunsPolicy()
);
private static void printPool() {
String format = String.format("coreSize:%s,maxSize:%s,avalableSize:%s", pool.getCorePoolSize(),
pool.getMaximumPoolSize(),
pool.getActiveCount());
System.out.println(format);
}
public static void execTask(String name) {
System.out.println(Thread.currentThread().getName()+" =======run");
if(name.equals("execute-exception")) {
System.out.println(1/0);
}
}
public static void main(String... args) throws InterruptedException {
pool.execute(()->execTask("execute-exception"));
TimeUnit.MILLISECONDS.sleep(10);
pool.execute(()->execTask("execute"));
pool.execute(()->execTask("execute"));
pool.execute(()->execTask("execute"));
printPool();
pool.shutdown();
}
}
执行结果:
线程池中线程异常,execute抛出异常;删除异常线程并新增一个空线程,且空线程名称是异常线程+1,后续线程池中没有异常线程;线程1,2互不影响
源码分析:
execute ThreadPoolExecutor.execute() ----> addWorker() ----->ThreadPoolExecutor.Worker().run() ----->ThreadPoolExecutor.runWorker()
runWorker()执行异常后,抛出异常,
processWorkerExit() 线程池中不会存在异常线程的线程
addWorker(null,false):空线程名称是在异常线程后,名称+1
new Worker(firstTask);
submit
pool.submit(()->execTask("execute"));
pool.submit(()->execTask("execute"));
Future<?> submit = pool.submit(() -> execTask("execute-exception"));
try {
submit.get();
} catch (ExecutionException e) {
e.printStackTrace();
}
pool.submit(()->execTask("execute"));
printPool();
pool.shutdown();
执行结果:
线程池中线程异常,sumbit不抛出异常,只有get结果时抛出异常;删除异常线程并新增一个空线程,且空线程名称是异常线程+1,后续线程池中没有异常线程;线程1,2互不影响
源码分析:
ThreadPoolExecutor.submit() ----> excute(furetask) ----> addWorker() ----> FutrueTask.run()
----> setException()
这个异常会不会在往外抛出,导致执行时不会报错
在执行完成后,get处理结果,抛出异常
----> FutrueTask.get()
----> FutrueTask.report()
相关内容