侧边栏壁纸
博主头像
月伴飞鱼 博主等级

行动起来,活在当下

  • 累计撰写 126 篇文章
  • 累计创建 31 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

如何实现主线程捕获子线程异常?

月伴飞鱼
2025-04-26 / 0 评论 / 1 点赞 / 5 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

在 Java 中,主线程无法直接捕获子线程抛出的异常,因为主线程与子线程是独立的执行单元,它们的执行是并行的。

子线程的异常通常在子线程内部处理,或者通过合适的机制传递给主线程。

不过,有几种方法可以实现主线程捕获子线程的异常:

1. 使用 FutureCallable

Future 允许主线程获取子线程的执行结果和异常。

当子线程抛出异常时,可以通过 Future.get() 方法将异常抛出到主线程,主线程可以捕获并处理这些异常。

示例代码:

import java.util.concurrent.*;

public class ThreadExceptionHandling {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        
        Callable<Integer> task = () -> {
            throw new RuntimeException("子线程异常");
        };
        
        Future<Integer> future = executor.submit(task);
        
        try {
            future.get();  // 这里会抛出子线程的异常
        } catch (ExecutionException e) {
            System.out.println("捕获到子线程异常: " + e.getCause().getMessage());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            executor.shutdown();
        }
    }
}

解释:

  • 使用 Callable 定义任务,它可以抛出异常。

  • 主线程通过 future.get() 获取子线程的执行结果。如果子线程抛出异常,get() 会抛出 ExecutionException,异常会被 getCause() 方法捕获。

2. 使用 UncaughtExceptionHandler

UncaughtExceptionHandler 是一个线程的未捕获异常处理器。

它可以处理没有被捕获的异常,适用于那些没有被 try-catch 捕获的异常。

示例代码:

public class HollisUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("线程 " + t.getName() + " 抛出未捕获异常:" + e.getMessage());
    }
}

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            throw new RuntimeException("这是一个未捕获异常");
        });

        thread.setUncaughtExceptionHandler(new HollisUncaughtExceptionHandler());
        thread.start();
    }
}

解释:

  • 创建一个自定义的 UncaughtExceptionHandler,并通过 setUncaughtExceptionHandler() 方法将其设置为线程的异常处理器。

  • 当线程抛出未捕获的异常时,uncaughtException 方法会被调用,主线程可以在其中处理异常。

3. 使用 CompletableFuture

CompletableFuture 提供了异步编程的支持,并且可以捕获子线程执行过程中的异常。

通过 handle()exceptionally() 方法,主线程可以捕获子线程抛出的异常并进行处理。

示例代码:

import java.util.concurrent.CompletableFuture;

public class CompletableFutureExample {
    public static void main(String[] args) {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            // 子线程抛出异常
            throw new RuntimeException("子线程异常");
        });

        future.handle((result, exception) -> {
            if (exception != null) {
                System.out.println("捕获到子线程异常: " + exception.getMessage());
            } else {
                System.out.println("子线程结果: " + result);
            }
            return null;
        });
    }
}

解释:

  • CompletableFuture.supplyAsync() 在子线程中执行任务,handle() 方法会处理子线程返回的结果或异常。

  • 如果子线程抛出异常,handle() 方法中的 exception 参数会非空,主线程可以在这里捕获并处理异常。

总结:

  • FutureCallable:允许主线程通过 Future.get() 获取子线程的结果或异常。

  • UncaughtExceptionHandler:为线程设置一个全局的异常处理器,处理未捕获的异常。

  • CompletableFuture:提供异步任务和异常处理功能,可以通过 handle()exceptionally() 方法处理异常。

1
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin
    1. 支付宝打赏

      qrcode alipay
    2. 微信打赏

      qrcode weixin
博主关闭了所有页面的评论