面试题答案
一键面试默认行为
当Java线程内抛出未捕获的异常时,默认行为是该线程会终止,并将异常信息打印到标准错误输出(System.err
)。
自定义处理机制
- 使用
Thread.UncaughtExceptionHandler
接口- 首先定义一个实现
Thread.UncaughtExceptionHandler
接口的类,重写uncaughtException
方法。在该方法中可以进行错误处理和日志记录等操作。
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread t, Throwable e) { // 这里进行日志记录,例如使用log4j等日志框架 System.err.println("线程 " + t.getName() + " 抛出未捕获的异常: " + e.getMessage()); e.printStackTrace(); } }
- 然后可以通过以下两种方式设置这个自定义的处理器:
- 为单个线程设置:
public class Main { public static void main(String[] args) { Thread thread = new Thread(() -> { throw new RuntimeException("测试未捕获异常"); }); thread.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler()); thread.start(); } }
- 为所有线程设置默认处理器:
public class Main { public static void main(String[] args) { Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler()); Thread thread = new Thread(() -> { throw new RuntimeException("测试未捕获异常"); }); thread.start(); } }
- 为单个线程设置:
- 首先定义一个实现
- 使用
ExecutorService
和Future
- 当使用
ExecutorService
提交任务时,可以通过Future
来获取任务执行结果并处理异常。
import java.util.concurrent.*; public class Main { public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); Future<?> future = executorService.submit(() -> { throw new RuntimeException("测试未捕获异常"); }); try { future.get(); } catch (InterruptedException | ExecutionException e) { // 处理异常 System.err.println("捕获到任务执行异常: " + e.getMessage()); e.printStackTrace(); } finally { executorService.shutdown(); } } }
- 在上述代码中,
future.get()
会阻塞等待任务完成,并在任务抛出异常时抛出ExecutionException
,可以在catch
块中进行异常处理。
- 当使用