一、初始化线程池
@Configuration
@EnableAsync
@Slf4j
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setKeepAliveSeconds(1000);// 空闲时间
taskExecutor.setCorePoolSize(5);// 线程池大小
taskExecutor.setMaxPoolSize(5);// 线程池最大线程数
taskExecutor.setQueueCapacity(0);// 最大等待任务数
taskExecutor.setThreadNamePrefix("thread-pool-");//前缀
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //拒绝策略
taskExecutor.initialize();
return taskExecutor;
}
/**
* 自定义异常处理
* @return
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new MyAsyncExceptionHandler();
}
static class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
String methodName = method.getName();
log.info("当前异常方法名,{}" , methodName);
}
}
}
二、配置说明
- corePoolSize 线程池维护线程的最少数量
- keepAliveSeconds 线程池维护线程所允许的空闲时间
- maxPoolSize 线程池维护线程的最大数量
- queueCapacity 线程池所使用的缓冲队列
当一个任务通过execute(Runnable)方法欲添加到线程池时:
- 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
- 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列workQueue未满,那么任务被放入缓冲队列。
- 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
- 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程 maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
- 当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
默认的四种拒绝策略:
- .AbortPolicy:默认拒绝策略,ThreadPoolExecutor中直接抛出异常不处理。
- CallerRunsPolicy:在任务被拒绝添加后,会调用当前线程池的所在的线程去执行被拒绝的任务。(哪个线程创建了线程池,这个线程来执行被拒绝的任务)
- DiscardPolicy:采用这个拒绝策略,会让被线程池拒绝的任务直接抛弃,不会抛异常也不会执行。
- DiscardOldestPolicy:策略的作用是,当任务被拒绝添加时,会抛弃任务队列中最旧的任务也就是最先加入队列的,再把这个新任务添加进去。
三、创建异步任务类
- 创建异步任务类
@Slf4j
@Service("asyncService")
public class AsyncService {
@Async
public void executorAsyncTask(String name){
log.info("执行异步:{}" ,name);
}
}