spring4.3.x 使用@Async注解实现异步执行 ThreadPoolExecutor did not accept task: AsyncExecutionInterceptor
程序员文章站
2022-05-22 20:21:30
...
@Async
首先我们需要了解其规则——@Async有两个限制:
- 必须仅应用在public方法上
- 自执行——从相同类中调用异步方法不起作用。
原因很简单——public方法能够被代理,自执行不工作是因为它绕过代理并直接调用底层方法。
-
处理调整报 Executor [[email protected][Running, pool size = 200, active threads = 1, queued tasks = 420, completed tasks = 244874312]] did not accept task: [email protected]4f9ae398
@Configuration
@ComponentScan("com.xxx.xxx.biz.*.*Service")
@EnableAsync
public class ThreadConfig extends AsyncConfigurerSupport{
@Override
public ThreadPoolTaskExecutor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心池的大小(即线程池中的线程数目大于这个参数时,提交的任务会被放进任务缓存队列)
executor.setCorePoolSize(50);
// 线程池最大能容忍的线程数
executor.setMaxPoolSize(500);
// 任务缓存队列,用来存放等待执行的任务
executor.setQueueCapacity(800);
executor.setWaitForTasksToCompleteOnShutdown(true);
// 线程池维护线程所允许的空闲时间
executor.setAwaitTerminationSeconds(60 * 30);
executor.setThreadNamePrefix("xxx-xxx-thread-");
// 线程池对拒绝任务(无线程可用)的处理策略 ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncUncaughtExceptionHandler() {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
log.warn("ThreadConfig处理异步常异-->{},{}",method.getName(),objects,throwable);
}
};
}
}
在ThreadPoolExecutor中表现为:
如果当前运行的线程数小于corePoolSize,那么就创建线程来执行任务(执行时需要获取全局锁)。
如果运行的线程大于或等于corePoolSize,那么就把task加入BlockQueue。
如果创建的线程数量大于BlockQueue的最大容量,那么创建新线程来执行该任务。
如果创建线程导致当前运行的线程数超过maximumPoolSize,就根据饱和策略来拒绝该任务。