​​​​​​        

目录

自定义线程池

1、通过实现 AsyncConfigurer类

2、继承 AsyncConfigurerSupport

3、自定义的 TaskExecutor 替代内置的任务执行器

拒绝策略


自定义线程池

1、通过实现 AsyncConfigurer类

@Configuration
@EnableAsync
@Slf4j
public class AsyncConfig implements AsyncConfigurer {

    /**
     * 异步任务使用的线程池
     * @return
     */
    // 替换掉默认的线程池
    @Bean(name = AsyncExecutionAspectSupport.DEFAULT_TASK_EXECUTOR_BEAN_NAME)
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心线程数量
        executor.setCorePoolSize(16);
        // 设置最大线程数量
        executor.setMaxPoolSize(160);
        // 线程空闲30s后进行销毁
        executor.setKeepAliveSeconds(30);
        // 使用线程池运行的线程名前缀
        executor.setThreadNamePrefix("shaoqing-");
        // 线程排队缓冲队列大小
        executor.setQueueCapacity(9999);
        // 使用自定义线程拒绝策略
        executor.setRejectedExecutionHandler(customizeRejectedExecutionHandler());
        // 初始化线程池
        executor.initialize();
        return executor;
    }

    /**
     * 线程运行时抛出异常处理逻辑
     * 如果异步方法有返回值,则不会执行此方法,而是通过异步方法的返回值通过try住get()方法,看是否有异常来判断处理的
     * @return
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (throwable, method, objects) -> {
            System.out.println("异常信息为:" + throwable);
            System.out.println("方法为:" + method.getName());
            System.out.println("参数信息为:" + objects);
        };
    }

    /**
     * 自定义线程池拒绝策略
     * @return
     */
    public RejectedExecutionHandler customizeRejectedExecutionHandler() {
        return (r, executor) -> {
//-------------------------------------------------------------------------
//            // 直接丢弃
//            return;
//-------------------------------------------------------------------------
            // 等10秒后再次加入队列
            // 如果队列还是满的,则会进入循环
            if (!executor.isShutdown()) {
                try {
                    log.info("线程池已满,线程进入休眠");
                    //线程休眠5秒
                    Thread.sleep(1000 * 10);
                } catch (InterruptedException e) {
                    log.error(e.getMessage());
                }
                // 再次尝试进入队列
                executor.execute(r);
            }
//-------------------------------------------------------------------------
        };
    }
}

2、继承 AsyncConfigurerSupport

        和方式1一样,就个是实现,一个是继承,本身AsyncConfigurerSupport实现AsyncConfigurer就实现了个寂寞,所有可以继续继承AsyncConfigurerSupport做实现

        代码实现:TODO

3、自定义的 TaskExecutor 替代内置的任务执行器

springboot中的异步调用(hello world)_子书少卿的博客-CSDN博客

拒绝策略

  1. ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常
  2. ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常
  3. ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务
  4. ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
  5. 自定义拒绝策略
  6. 一些其他组件可能也会实现RejectedExecutionHandler接口做拒绝策略的实现,也可以使用

问题:

        1、第三种方式如何处理异常的?

        2、在线程池中拿到异常信息后在异步方法中是否还能捕获异常?

                - 线程池中只能获取没有返回值类型的异步方法的异常

                - 如果异步方法有返回值,则不会被线程池的异常处理捕获,如果要处理异常需要获取到异步方法的返回值,判断返回值的get()方法是否有异常来判断处理。

05-20 02:39