多线程异常需特殊处理:1. 通过setUncaughtExceptionHandler捕获未受检异常;2. Runnable任务内需自行try-catch;3. Callable任务异常由Future.get()抛出ExecutionException;4. 可设置默认处理器全局监听。应根据并发模型选择对应策略,避免异常被忽略。

在Java中,多线程异常不能像普通代码那样通过外层try-catch直接捕获。线程内部抛出的未检查异常(如RuntimeException)会默认终止该线程,但不会通知主线程或影响其他线程。要正确处理多线程中的异常,需要采用特定机制。
使用UncaughtExceptionHandler捕获未捕获异常
每个线程都可以设置一个UncaughtExceptionHandler,用于处理线程运行过程中未被捕获的异常。
可以通过以下方式设置:
- 为单个线程设置处理器:
Thread thread = new Thread(() -> {
throw new RuntimeException("线程内异常");
});
thread.setUncaughtExceptionHandler((t, e) -> {
System.out.println("线程 " + t.getName() + " 发生异常: " + e.getMessage());
});
thread.start();
- 为所有线程设置默认处理器:
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
System.out.println("全局捕获 - 线程 " + t.getName() + " 异常: " + e.getMessage());
});
在线程任务中主动捕获异常
对于Runnable任务,由于run()方法不抛出异常,必须在任务内部自行try-catch。
立即学习“Java免费学习笔记(深入)”;
Runnable task = () -> {
try {
// 可能出错的操作
int result = 10 / 0;
} catch (Exception e) {
System.out.println("任务中捕获异常: " + e.getMessage());
}
};
new Thread(task).start();
使用Callable和Future获取异常
如果使用ExecutorService提交Callable任务,异常会在调用get()时以ExecutionException形式抛出。
ExecutorService executor = Executors.newSingleThreadExecutor(); Futurefuture = executor.submit(() -> { throw new RuntimeException("Callable异常"); }); try { Integer result = future.get(); // 此处会抛出ExecutionException } catch (ExecutionException e) { System.out.println("捕获任务异常: " + e.getCause().getMessage()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } executor.shutdown();
基本上就这些。关键是根据使用的并发模型选择合适的方式:Runnable需内部捕获,Callable可通过Future获取,未捕获的异常则依赖UncaughtExceptionHandler。这样能确保异常不被静默吞掉,便于调试和恢复。










