Spring @Async之二:SpringBoot 自定义线程池,修改springboot的默认线程池
本文内容纲要:
-1.自定义线程池
-2.配置spring/springboot默认的异步线程池
本教程目录:
- 自定义线程池
- 配置spring默认的线程池
1.自定义线程池
1.1修改application.properties
task.pool.corePoolSize=20
task.pool.maxPoolSize=40
task.pool.keepAliveSeconds=300
task.pool.queueCapacity=50
1.2线程池配置属性类TaskThreadPoolConfig.java
importorg.springframework.boot.context.properties.ConfigurationProperties;
/**
*线程池配置属性类
*/
@ConfigurationProperties(prefix="task.pool")
publicclassTaskThreadPoolConfig{
privateintcorePoolSize;
privateintmaxPoolSize;
privateintkeepAliveSeconds;
privateintqueueCapacity;
//...getterandsettermethods...
}
1.3创建线程池TaskExecutePool.java
/**
*创建线程池
*/
@Configuration
@EnableAsync
publicclassTaskExecutePool{
@Autowired
privateTaskThreadPoolConfigconfig;
@Bean
publicExecutormyTaskAsyncPool(){
ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor();
//核心线程池大小
executor.setCorePoolSize(config.getCorePoolSize());
//最大线程数
executor.setMaxPoolSize(config.getMaxPoolSize());
//队列容量
executor.setQueueCapacity(config.getQueueCapacity());
//活跃时间
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
//线程名字前缀
executor.setThreadNamePrefix("MyExecutor-");
//setRejectedExecutionHandler:当pool已经达到maxsize的时候,如何处理新任务
//CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true);
```executor.setAwaitTerminationSeconds(60
);`
executor.initialize();
returnexecutor;
}
}
上面我们通过使用ThreadPoolTaskExecutor
创建了一个线程池,同时设置了以下这些参数:
- 核心线程数20:线程池创建时候初始化的线程数
- 最大线程数40:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
- 缓冲队列50:用来缓冲执行任务的队列
- 允许线程的空闲时间300秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
- 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
- 线程池对拒绝任务的处理策略:这里采用了
CallerRunsPolicy
策略,当线程池没有处理能力的时候,该策略会直接在execute方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
(ThreadPoolExecutor.AbortPolicy丢弃任务并抛出RejectedExecutionException异常(默认)。
ThreadPoolExecutor.DiscardPolic丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy丢弃队列最前面的任务,然后重新尝试执行任务
ThreadPoolExecutor.CallerRunsPolic由调用线程处理该任务)
说明:setWaitForTasksToCompleteOnShutdown(true)
该方法就是这里的关键,用来设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean,这样这些异步任务的销毁就会先于Redis线程池的销毁。同时,这里还设置了setAwaitTerminationSeconds(60),该方法用来设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住。
1.4创建线程任务
@Component
publicclassAsyncTask{
protectedfinalLoggerlogger=LoggerFactory.getLogger(this.getClass());
@Async("myTaskAsyncPool")//myTaskAsynPool即配置线程池的方法名,此处如果不写自定义线程池的方法名,会使用默认的线程池
publicvoiddoTask1(inti)throwsInterruptedException{
logger.info("Task"+i+"started.");
}
}
1.5修改启动类
给启动类添加注解
@EnableAsync
@EnableConfigurationProperties({TaskThreadPoolConfig.class})//开启配置属性支持
1.6测试
protectedfinalLoggerlogger=LoggerFactory.getLogger(this.getClass());
@Autowired
privateAsyncTaskasyncTask;
@Test
publicvoidAsyncTaskTest()throwsInterruptedException,ExecutionException{
for(inti=0;i<100;i++){
asyncTask.doTask1(i);
}
logger.info("Alltasksfinished.");
}
2.配置spring/springboot默认的异步线程池
因为上面的那个线程池使用时候总要加注解@Async("myTaskAsyncPool")
,(会影响业务系统中的多处修改)
如果我们想使用默认的线程池,即使用异步线程池时还是使用@Async的注解。但是只是想修改默认线程池的配置,将默认的异步线程池的参数可配置化,方便系统的调优。那怎么做了,此时我们需要实现AsyncConfigurer类,示例代码如下:
publicinterfaceAsyncConfigurer{
ExecutorgetAsyncExecutor();
AsyncUncaughtExceptionHandlergetAsyncUncaughtExceptionHandler();
}
说明:
Executor:处理异步方法调用时要使用的实例,
AsyncUncaughtExceptionHandler:在使用void
返回类型的异步方法执行期间抛出异常时要使用的实例。
2.1获取属性配置类
这个和上面的TaskThreadPoolConfig类相同,这里不重复
2.2NativeAsyncTaskExecutePool.java装配线程池
/**
*原生(Spring)异步任务线程池装配类
*/
@Slf4j
@Configuration
publicclassNativeAsyncTaskExecutePoolimplementsAsyncConfigurer{
//注入配置类
@Autowired
TaskThreadPoolConfigconfig;
@Override
publicExecutorgetAsyncExecutor(){
ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor();
//核心线程池大小
executor.setCorePoolSize(config.getCorePoolSize());
//最大线程数
executor.setMaxPoolSize(config.getMaxPoolSize());
//队列容量
executor.setQueueCapacity(config.getQueueCapacity());
//活跃时间
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
//线程名字前缀
executor.setThreadNamePrefix("MyExecutor-");
//setRejectedExecutionHandler:当pool已经达到maxsize的时候,如何处理新任务
//CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
returnexecutor;
}
/**
*异步任务中异常处理
*@return
*/
@Override
publicAsyncUncaughtExceptionHandlergetAsyncUncaughtExceptionHandler(){
returnnewAsyncUncaughtExceptionHandler(){
@Override
publicvoidhandleUncaughtException(Throwablearg0,Methodarg1,Object...arg2){
log.error("=========================="+arg0.getMessage()+"=======================",arg0);
log.error("exceptionmethod:"+arg1.getName());
}
};
}
}
2.3线程任务类AsyncTask.java
@Component
publicclassAsyncTask{
protectedfinalLoggerlogger=LoggerFactory.getLogger(this.getClass());
@Async
publicvoiddoTask2(inti)throwsInterruptedException{
logger.info("Task2-Native"+i+"started.");
}
}
2.4测试
@Test
publicvoidAsyncTaskNativeTest()throwsInterruptedException,ExecutionException{
for(inti=0;i<100;i++){
asyncTask.doTask2(i);
}
logger.info("Alltasksfinished.");
}
结果:
2018-03-2521:23:07.655INFO4668---[MyExecutor-8]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native6started.
2018-03-2521:23:07.655INFO4668---[MyExecutor-3]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native1started.
2018-03-2521:23:07.655INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native7started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native21started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native22started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native23started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native24started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native25started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native26started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native27started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native28started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native29started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native30started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native31started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native32started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native33started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native34started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native35started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native36started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native37started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native38started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native39started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native40started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native41started.
2018-03-2521:23:07.657INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native42started.
2018-03-2521:23:07.657INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native43started.
2018-03-2521:23:07.657INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native44started.
2018-03-2521:23:07.657INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native45started.
2018-03-2521:23:07.657INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native46started.
2018-03-2521:23:07.658INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native47started.
2018-03-2521:23:07.655INFO4668---[MyExecutor-7]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native5started.
2018-03-2521:23:07.658INFO4668---[MyExecutor-7]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native49started.
2018-03-2521:23:07.658INFO4668---[MyExecutor-7]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native50started.
2018-03-2521:23:07.658INFO4668---[MyExecutor-11]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native9started.
2018-03-2521:23:07.655INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native4started.
2018-03-2521:23:07.659INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native53started.
2018-03-2521:23:07.659INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native54started.
2018-03-2521:23:07.659INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native55started.
2018-03-2521:23:07.659INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native56started.
2018-03-2521:23:07.659INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native57started.
2018-03-2521:23:07.659INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native58started.
2018-03-2521:23:07.660INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native59started.
2018-03-2521:23:07.660INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native60started.
2018-03-2521:23:07.660INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native61started.
2018-03-2521:23:07.660INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native62started.
2018-03-2521:23:07.660INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native63started.
2018-03-2521:23:07.660INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native64started.
2018-03-2521:23:07.660INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native65started.
2018-03-2521:23:07.660INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native66started.
2018-03-2521:23:07.660INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native67started.
2018-03-2521:23:07.660INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native68started.
2018-03-2521:23:07.655INFO4668---[MyExecutor-5]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native3started.
2018-03-2521:23:07.655INFO4668---[MyExecutor-4]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native2started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-8]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native19started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-2]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native0started.
2018-03-2521:23:07.656INFO4668---[MyExecutor-3]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native20started.
2018-03-2521:23:07.657INFO4668---[MyExecutor-10]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native8started.
2018-03-2521:23:07.658INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native48started.
2018-03-2521:23:07.658INFO4668---[MyExecutor-7]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native51started.
2018-03-2521:23:07.658INFO4668---[MyExecutor-11]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native52started.
2018-03-2521:23:07.658INFO4668---[MyExecutor-12]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native10started.
2018-03-2521:23:07.661INFO4668---[MyExecutor-13]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native11started.
2018-03-2521:23:07.662INFO4668---[MyExecutor-14]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native12started.
2018-03-2521:23:07.662INFO4668---[MyExecutor-15]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native13started.
2018-03-2521:23:07.663INFO4668---[MyExecutor-16]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native14started.
2018-03-2521:23:07.663INFO4668---[MyExecutor-17]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native15started.
2018-03-2521:23:07.663INFO4668---[MyExecutor-18]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native16started.
2018-03-2521:23:07.663INFO4668---[MyExecutor-19]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native17started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-20]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native18started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-21]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native69started.
2018-03-2521:23:07.664INFO4668---[main]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native89started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-6]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native90started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-22]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native70started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-5]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native91started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-5]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native92started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-8]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native93started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-2]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native94started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-10]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native95started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-3]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native96started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-7]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native98started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-9]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native97started.
2018-03-2521:23:07.664INFO4668---[MyExecutor-11]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native99started.
2018-03-2521:23:07.664INFO4668---[main]com.laojiao.securitydemo.ControllerTest:Alltasksfinished.
2018-03-2521:23:07.666INFO4668---[MyExecutor-23]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native71started.
2018-03-2521:23:07.667INFO4668---[MyExecutor-24]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native72started.
2018-03-2521:23:07.667INFO4668---[MyExecutor-25]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native73started.
2018-03-2521:23:07.669INFO4668---[MyExecutor-26]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native74started.
2018-03-2521:23:07.669INFO4668---[MyExecutor-27]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native75started.
2018-03-2521:23:07.673INFO4668---[MyExecutor-28]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native76started.
2018-03-2521:23:07.674INFO4668---[MyExecutor-29]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native77started.
2018-03-2521:23:07.674INFO4668---[MyExecutor-30]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native78started.
2018-03-2521:23:07.676INFO4668---[MyExecutor-31]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native79started.
2018-03-2521:23:07.677INFO4668---[MyExecutor-32]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native80started.
2018-03-2521:23:07.677INFO4668---[MyExecutor-33]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native81started.
2018-03-2521:23:07.677INFO4668---[MyExecutor-34]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native82started.
2018-03-2521:23:07.678INFO4668---[MyExecutor-35]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native83started.
2018-03-2521:23:07.679INFO4668---[MyExecutor-36]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native84started.
2018-03-2521:23:07.679INFO4668---[MyExecutor-37]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native85started.
2018-03-2521:23:07.679INFO4668---[MyExecutor-38]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native86started.
2018-03-2521:23:07.680INFO4668---[MyExecutor-39]c.l.securitydemo.mythreadpool.AsyncTask:Task2-Native87started.
2018-03-2521:23:07.680INFO4668---[MyExecutor-
本文内容总结:1.自定义线程池,2.配置spring/springboot默认的异步线程池,
原文链接:https://www.cnblogs.com/duanxz/p/6084494.html