- 线程池状态:
- 即使部分任务执行抛出未处理异常,线程池一旦调用
shutdown()
方法,在任务执行完后,线程池最终还是会进入TERMINATED
状态。异常的抛出不会改变线程池从SHUTDOWN
到TERMINATED
的正常状态转换流程。
- 对后续任务的影响:
- 调用
shutdown()
方法后,线程池不再接受新任务,但会继续执行队列中已有的任务。如果部分任务执行抛出未处理异常,异常线程会终止,但是线程池中的其他线程会继续尝试从任务队列中获取任务并执行。直到任务队列为空且所有工作线程都终止,线程池才会进入TERMINATED
状态。
- 捕获并处理异常的方式:
- 使用
try - catch
块:
在任务的run
方法中直接使用try - catch
块捕获异常。例如:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExceptionHandling {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(() -> {
try {
// 模拟可能抛出异常的任务
if (Math.random() < 0.5) {
throw new RuntimeException("Task failed");
}
System.out.println("Task executed successfully");
} catch (Exception e) {
System.err.println("Caught exception in task: " + e.getMessage());
}
});
executorService.shutdown();
}
}
- 使用
Thread.UncaughtExceptionHandler
:
可以为线程池中的线程设置UncaughtExceptionHandler
。例如:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExceptionHandling2 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
System.err.println("Uncaught exception in thread " + t.getName() + ": " + e.getMessage());
});
executorService.submit(() -> {
// 模拟可能抛出异常的任务
if (Math.random() < 0.5) {
throw new RuntimeException("Task failed");
}
System.out.println("Task executed successfully");
});
executorService.shutdown();
}
}
- 使用
Future
:
通过submit
方法返回的Future
对象来获取任务执行结果并捕获异常。例如:
import java.util.concurrent.*;
public class ThreadPoolExceptionHandling3 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
Future<?> future = executorService.submit(() -> {
// 模拟可能抛出异常的任务
if (Math.random() < 0.5) {
throw new RuntimeException("Task failed");
}
System.out.println("Task executed successfully");
return null;
});
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
System.err.println("Caught exception: " + e.getMessage());
}
executorService.shutdown();
}
}