目录
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博客
拒绝策略
- ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常
- ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常
- ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务
- ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
- 自定义拒绝策略
- 一些其他组件可能也会实现RejectedExecutionHandler接口做拒绝策略的实现,也可以使用
问题:
1、第三种方式如何处理异常的?
2、在线程池中拿到异常信息后在异步方法中是否还能捕获异常?
- 线程池中只能获取没有返回值类型的异步方法的异常
- 如果异步方法有返回值,则不会被线程池的异常处理捕获,如果要处理异常需要获取到异步方法的返回值,判断返回值的get()方法是否有异常来判断处理。