MST

星途 面试题库

面试题:Java自定义异常在多线程环境下的处理与异常链传递

在多线程的Java应用中,当一个线程抛出自定义异常,如何通过异常链将该异常准确传递给主线程进行统一处理?请考虑线程安全以及异常链中异常信息的完整性,给出详细的实现思路和关键代码片段。
41.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 自定义异常类:创建自定义异常类,确保可以保存异常相关信息。
  2. 线程执行体:在线程的执行方法(如run方法)中捕获自定义异常,并通过ThreadLocal来存储异常信息,以保证线程安全。
  3. 主线程处理:主线程等待子线程执行完毕后,从ThreadLocal中获取异常信息,如果存在异常,则通过异常链将其抛出,确保异常信息的完整性。

关键代码片段

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CustomExceptionThread {
    // 自定义异常类
    static class MyCustomException extends Exception {
        public MyCustomException(String message) {
            super(message);
        }
    }

    // ThreadLocal用于存储每个线程的异常
    private static final ThreadLocal<Throwable> threadLocalException = ThreadLocal.withInitial(() -> null);

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(() -> {
            try {
                // 模拟业务逻辑,可能抛出异常
                throw new MyCustomException("这是一个自定义异常");
            } catch (MyCustomException e) {
                // 捕获异常并存储到ThreadLocal
                threadLocalException.set(e);
            }
        });
        executorService.shutdown();

        // 等待线程执行完毕
        while (!executorService.isTerminated()) {
            // 等待
        }

        // 从ThreadLocal获取异常并处理
        Throwable exception = threadLocalException.get();
        if (exception != null) {
            // 通过异常链传递异常
            RuntimeException wrapperException = new RuntimeException("子线程抛出异常", exception);
            throw wrapperException;
        }
        threadLocalException.remove();
    }
}

在上述代码中:

  1. MyCustomException:定义了自定义异常类。
  2. threadLocalException:使用ThreadLocal来存储每个线程中的异常,保证线程安全。
  3. main方法:在子线程中捕获自定义异常并存储到ThreadLocal,主线程等待子线程执行完毕后,从ThreadLocal获取异常并通过异常链传递给主线程进行处理,最后调用threadLocalException.remove()清理ThreadLocal中的数据,避免内存泄漏。