ThreadPoolExecutor获取原始异常

ThreadPoolExecutor作用

ThreadPoolTaskExecutor是Spring框架提供的一个线程池实现,它是基于Java的ThreadPoolExecutor实现的。ThreadPoolTaskExecutor可以管理线程池中的线程,以满足多线程并发执行任务的需要。

FutureTask作用

FutureTask的主要作用是在多线程环境下,获取异步执行的结果。在执行该任务时,可以通过Future接口的get()方法来获取任务的执行结果,而不必串行阻塞等待。由此,FutureTask可以通过异步的方式充分利用服务器资源,提高代码的执行效率与响应速度。

get方法可能会阻塞当前线程,如果任务还没有执行完成,会一直等待,直到任务执行完成后返回结果。如果不想等待任务执行完成,可以使用isDone方法判断任务是否已经执行完成。

ThreadPoolTaskExecutor配合Future使用
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

public class ThreadPoolTaskExecutorWithFutureExample {
    public static void main(String[] args) throws Exception {
        //配置ThreadPoolTaskExecutor
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(50);
        executor.setThreadNamePrefix("MyThreadPool-");
        executor.initialize();

        MyTask task = new MyTask();
        //使用executor.submit()方法提交任务到线程池中执行,并得到Future对象。
        Future<Integer> future = executor.submit(task);
				//在需要的时候调用future.get()方法获取任务的执行结果,如果任务还没有执行完成,该方法将阻塞当前线程直到任务执行完成。
        int result = future.get();
        System.out.println("Result: " + result);

        executor.shutdown();
    }

  	/**
     * //创建一个实现Callable接口的任务类,该类封装了要执行的任务,并返回结果。
     */
    static class MyTask implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            return 1 + 1;
        }
    }
}
ThreadPoolTaskExecutor异常处理

下面是一段会出现异常的代码:

public class ThreadPoolTaskExecutorWithFutureExample {
    public static void main(String[] args) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        try {
            //配置ThreadPoolTaskExecutor
            executor.setCorePoolSize(5);
            executor.setMaxPoolSize(10);
            executor.setQueueCapacity(50);
            executor.setThreadNamePrefix("MyThreadPool-");
            executor.initialize();

            MyTask task = new MyTask();
            Future<Integer> future = executor.submit(task);

            int result = future.get();
            System.out.println("Result: " + result);

            executor.shutdown();
        } catch (Exception e) {
            System.out.println(e.getCause().getMessage());
        }
    }

    /**
     * //创建一个实现Callable接口的任务类,该类封装了要执行的任务,并返回结果。
     */
    static class MyTask implements Callable<Integer> {
        @Override
        public Integer call() {
            //抛出异常
            int i = 1 / 0;
            return 1 + 1;
        }
    }
}

异常日志:

在这里插入图片描述

可以看到,控制台只是以info级别日志打印了以上异常信息。那么异常信息将会在info日志文件中记录。这样不利于错误排查,显然不符合生产环境要求!

解决方案
一:重写ThreadPoolExecutorAfterExecute
public class ThreadPoolExecutorAfterExecuteExample {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()) {
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
                if (t == null) {
                    System.out.println("Task " + r.toString() + " completed successfully");
                } else {
                    System.out.println("Task " + r.toString() + " failed with exception: " + t.getMessage());
                }
            }
        };

        executor.execute(() -> {
            System.out.println("Task 1");
            throw new RuntimeException("Task 1 failed");
        });

        executor.execute(() -> {
            System.out.println("Task 2");
        });

        executor.execute(() -> {
            System.out.println("Task 3");
            throw new RuntimeException("Task 3 failed");
        });

        executor.shutdown();
    }
}

在这里插入图片描述

二:手动抛出新的异常
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    try {
        //配置ThreadPoolTaskExecutor
        executor.setCorePoolSize(5);
				//配置代码

        int result = future.get();
        System.out.println("Result: " + result);
        executor.shutdown();
    } catch (Exception e) {
        System.out.println(e.getCause().getMessage());
        //手动创建抛出异常
        throw new RuntimeException(e);
    }
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThreadPoolExecutor是Python中的一个线程池实现,它可以用于管理和调度多个线程执行任务。当线程池中的线程执行任务时,如果任务抛出异常,我们可以通过以下几种方式获取异常信息: 1. 使用submit()方法提交任务并返回一个Future对象,通过调用Future对象的result()方法获取任务执行的结果。如果任务抛出异常,result()方法会将异常重新抛出,我们可以使用try-except语句捕获并处理异常。 ```python import concurrent.futures def task(): # 任务逻辑 raise Exception("Something went wrong") with concurrent.futures.ThreadPoolExecutor() as executor: future = executor.submit(task) try: result = future.result() except Exception as e: print("Exception:", e) ``` 2. 使用add_done_callback()方法注册一个回调函数,在任务执行完成后自动调用该函数。回调函数的参数是一个Future对象,我们可以通过调用Future对象的exception()方法获取任务执行过程中抛出的异常信息。 ```python import concurrent.futures def task(): # 任务逻辑 raise Exception("Something went wrong") def handle_exception(future): try: result = future.result() except Exception as e: print("Exception:", e) with concurrent.futures.ThreadPoolExecutor() as executor: future = executor.submit(task) future.add_done_callback(handle_exception) ``` 这样,当任务执行完成后,handle_exception()函数会被自动调用,并且可以获取到任务执行过程中抛出的异常信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值