Thinking in Java学习笔记 Thread.UncaughtExceptionHandler接口实现捕获线程内异常

本文介绍了如何实现自定义类以实现Thread.UncaughtExceptionHandler接口,并通过定制的ThreadFactory创建ExecutorService实例来捕获线程中的异常。

实现自定义类来实现Thread.UncaughtExceptionHandler接口,在unCaughtExceptionHandler方法中编写自已需要的处理代码

实现自定义的ThreadFactory,newThread的时候调用setUncaughtExceptionHandler方法来指定自定义的UncaughtExceptionHandler

使用自定的ThreadFactory来创建ExecutorService实例

运行线程,即可捕获线程中的异常



package com.test.concurrent;

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

public class CaptureUncaughtException {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ExecutorService exec=Executors.newCachedThreadPool(new MyThreadFactory());
		exec.execute(new UncaughtThread());
	}

}

class UncaughtThread implements Runnable{
	@Override
	public void run(){
		Thread t=Thread.currentThread();
		System.out.println("uncaught exception:"+t.getUncaughtExceptionHandler());
		throw new RuntimeException("uncaught runtime exception");
	}
}
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{

	@Override
	public void uncaughtException(Thread t, Throwable e) {
		// TODO Auto-generated method stub
		System.out.println("get Exception !!!:"+e);
	}
	
}
class MyThreadFactory implements ThreadFactory{

	@Override
	public Thread newThread(Runnable r) {
		// TODO Auto-generated method stub
		Thread t=new Thread(r);
		t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
		return t;
	}
	
}


代码概述 本题涉及 Java 中**异步线程异常捕获机制**。在多线程编程中,由于线程是独立运行的,主线程无法直接捕获线程中的异常,因此需要特定的机制来处理异步线程中的异常。 代码解析 在 Java 中,线程异常处理机制不同于主线程。如果在 `Thread` 或 `Runnable` 中抛出异常,它不会传播到主线程,而是由 JVM 调用 `Thread.UncaughtExceptionHandler` 来处理。 ### 1. 使用 `try-catch` 在 `run` 方法内部捕获异常 ```java new Thread(() -> { try { // 可能抛异常的代码 int result = 10 / 0; } catch (Exception e) { e.printStackTrace(); } }).start(); ``` ✅ 优点:简单直接 ❌ 缺点:每个线程都要单独处理,不适合大规模并发任务 --- ### 2. 自定义 `UncaughtExceptionHandler` 可以为每个线程设置未捕获异常的处理逻辑: ```java Thread thread = new Thread(() -> { int result = 10 / 0; }); thread.setUncaughtExceptionHandler((t, e) -> { System.out.println("线程 " + t.getName() + " 出现异常:" + e.getMessage()); }); thread.start(); ``` ✅ 优点:统一处理线程异常 ❌ 缺点:只能处理未被捕获异常 --- ### 3. 使用 `Future` 和 `ExecutorService` 捕获异常(适用于 `Callable`) ```java ExecutorService executor = Executors.newSingleThreadExecutor(); Future<?> future = executor.submit(() -> { int result = 10 / 0; return null; }); try { future.get(); // 获取任务结果,会抛出异常 } catch (ExecutionException e) { System.out.println("捕获到异步任务异常:" + e.getCause().getMessage()); } finally { executor.shutdown(); } ``` ✅ 优点:适合任务调度和返回结果的异常捕获 ❌ 缺点:需要管理 `ExecutorService` 生命周期 --- ### 4. 使用 `CompletableFuture` 捕获异常(推荐用于异步编排) ```java CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { int result = 10 / 0; }); future.exceptionally(ex -> { System.out.println("捕获异常:" + ex.getMessage()); return null; }); ``` ✅ 优点:支持链式调用和统一异常处理 ❌ 缺点:对异常处理需熟悉 CompletableFuture API --- 知识点 1. **线程异常处理机制**:线程内部异常不会自动传播给主线程,需显式捕获或设置 `UncaughtExceptionHandler`。 2. **Future 异常捕获**:通过 `get()` 方法获取任务结果时,可捕获 `ExecutionException` 并提取异常信息。 3. **CompletableFuture 异常处理**:提供 `exceptionally` 等方法用于链式异步任务的统一异常处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值