- 任务抛出异常对线程池的影响:
- 当线程池中的某个任务抛出未捕获的异常时,默认情况下,该线程会终止。但线程池本身不会因此停止运行,线程池会创建新的线程(如果线程数未达到最大线程数且需要处理后续任务)来替代终止的线程,以维持线程池的正常工作。然而,如果异常频繁出现导致线程频繁终止和创建,可能会影响系统性能。
- 捕获和处理异常的方法:
- 使用
try - catch
块:在任务的run
方法内部(如果是Runnable
任务)或call
方法内部(如果是Callable
任务)添加try - catch
块来捕获异常。例如:
class MyTask implements Callable<Integer> {
@Override
public Integer call() throws Exception {
try {
// 任务逻辑
return 1;
} catch (Exception e) {
// 处理异常
System.out.println("Caught exception: " + e.getMessage());
return -1;
}
}
}
- 使用
Future
获取异常:如果提交的是Callable
任务,可以通过Future
的get
方法获取任务执行结果,同时捕获ExecutionException
来获取任务中抛出的异常。例如:
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future<Integer> future = executorService.submit(new MyTask());
try {
Integer result = future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
- 自定义
Thread.UncaughtExceptionHandler
:可以为线程池中的线程设置UncaughtExceptionHandler
。例如:
ThreadFactory threadFactory = Executors.defaultThreadFactory();
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
System.out.println("Uncaught exception in thread " + t.getName() + ": " + e.getMessage());
});
ExecutorService executorService = Executors.newFixedThreadPool(10, threadFactory);
- 使用
ThreadPoolExecutor
的afterExecute
方法:继承ThreadPoolExecutor
并重写afterExecute
方法,在任务执行完毕后(无论是否抛出异常)进行异常处理。例如:
class CustomThreadPoolExecutor extends ThreadPoolExecutor {
public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t != null) {
System.out.println("Exception in task: " + t.getMessage());
}
}
}