Java线程池-execute方法和submit方法,异常处理有何不同
目录
Java线程池 execute方法和submit方法,异常处理有何不同?
在 Java 线程池中,
execute
方法和
submit
方法都用于向线程池提交任务,但它们在异常处理方面存在显著差异,下面为你详细介绍。
方法概述
execute方法 :execute方法是Executor接口定义的方法,在ThreadPoolExecutor类中实现,用于提交一个Runnable任务到线程池执行。submit方法 :submit方法是ExecutorService接口定义的方法,有多个重载版本,可接受Runnable或Callable任务,并且会返回一个Future对象,用于获取任务的执行结果。
异常处理差异
1. 异常抛出方式
execute方法- 当使用
execute方法提交Runnable任务时,如果任务在执行过程中抛出未捕获的异常,该异常会直接抛给线程池中的工作线程。 - 若没有为线程设置
UncaughtExceptionHandler,异常会导致工作线程终止,线程池会记录该异常的堆栈信息并打印到控制台。
- 当使用
submit方法- 当使用
submit方法提交Runnable或Callable任务时,任务执行过程中抛出的异常不会直接抛出,而是被封装在Future对象中。 - 只有当调用
Future对象的get方法时,才会以ExecutionException的形式抛出,其getCause方法可获取实际的异常。
- 当使用
2. 异常捕获方式
execute方法- 若要捕获
execute方法提交任务的异常,可在Runnable任务的run方法中使用try-catch块捕获异常,或者通过自定义ThreadFactory为线程设置UncaughtExceptionHandler来捕获未处理的异常。
- 若要捕获
submit方法- 对于
submit方法提交的任务,可通过Future对象的get方法捕获异常。在调用get方法时,使用try-catch块捕获ExecutionException,再通过getCause方法获取实际的异常。
- 对于
示例代码
execute 方法异常处理示例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecuteExceptionHandling {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(() -> {
try {
// 模拟抛出异常的代码
int result = 1 / 0;
} catch (Exception e) {
System.out.println("在任务中捕获到异常: " + e.getMessage());
}
});
executorService.shutdown();
}
}submit 方法异常处理示例
import java.util.concurrent.*;
public class SubmitExceptionHandling {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Integer> future = executorService.submit(() -> {
// 模拟抛出异常的代码
return 1 / 0;
});
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
System.out.println("通过 Future 捕获到异常: " + e.getCause().getMessage());
}
executorService.shutdown();
}
}总结
execute方法提交的任务抛出异常时,异常会直接影响工作线程,需要在任务内部或通过线程的UncaughtExceptionHandler进行处理。submit方法提交的任务抛出异常时,异常会被封装在Future对象中,需要通过调用Future的get方法并捕获ExecutionException来处理。如果没有手动在子线程中捕获异常,也没有在主线程中调用futureTask.get(),那么异常就相当于被系统吞掉了,这是相当危险的,出了问题无法定位!!!。