基于Springboot获取ThreadPoolTaskExecutor
1.创建一个类,加载获取ThreadPoolTaskExecutor ;
@EnableAsync
@Configuration
public class AsyncTask {
/**
* 线程池维护线程的最小数量
*/
private final int corePoolSize = 10;
/**
* 线程池维护线程的最大数量
*/
private final int maxPoolSize = 200;
/**
* 队列最大长度
*/
private final int queueCapacity = 500;
/**
* 保持时间
*/
private final int keepAliveSeconds = 120000;
/**
* @MethodName buildExecutor
* @Author 热心村民
* @Description 获取ThreadPoolTaskExecutor
* @Param [logPrefix] 异步任务的线程名称前缀
* @return org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
* @Date 2019/12/13 10:11
**/
private ThreadPoolTaskExecutor buildExecutor(String logPrefix) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(this.maxPoolSize);
executor.setCorePoolSize(this.corePoolSize);
executor.setThreadNamePrefix(logPrefix + "-");
executor.setQueueCapacity(this.queueCapacity);
executor.setKeepAliveSeconds(this.keepAliveSeconds);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
这里对几个数据做解释:
corePoolSize :创建线程的最小数量,当线程池中线程数量小于这个数时就会创建新的线程来处理任务;
queueCapacity :队列长度;这个队列在这里的作用是,当线程池中维护的最小线程数都在处理任务时,新来的任务不会马上创建新线程执行,而是放入这个阻塞队列中,等待空闲线程来执行它;
maxPoolSize :线程池维护的最大线程数量;当维护的最小线程数都在执行任务,并且阻塞队列中也放不下新的任务时,就会创建新的线程放入线程池,并处理任务;当新建的线程达到了最大的维护数量时,则会由RejectedExecutionHandler来抛出拒绝处理的异常,并且有处理策略,这里不说了;
keepAliveSeconds:空闲线程的保持时间,当空闲的线程在等待了该时间后任然空闲,则自行销毁;
logPrefix:这里是为异步任务做的处理,异步任务处理线程的名称前缀,方便后面设置异步任务;
2.配置异步任务;
在线程池这个类中添加方法:
这里两个名称可以自定义;异步任务名称主要是为了在使用异步方法的注解@Async时,可以用来定位到对应的executor方法来获取相应的线程;
@Bean(name = "异步任务名称")
public Executor AsyncTestExecutor() {
return this.buildExecutor("异步任务线程名称前缀");
}
3.异步任务处理;
这里就完成你需要异步处理的业务的代码;并使用@Async注解让方法变成异步方法;并指定name,对应到刚才的线程excutor;
@Component
public class AsyncTestService {
/**
* @MethodName forTest
* @Author 热心村民
* @Description 异步方法
* @Param []
* @return void
* @Date 2019/12/12 11:48
**/
@Async("异步任务名称")
public void forTest() {
for (int i = 0; i <= 7 ; i++){
try {
new Thread().sleep(2000);
System.out.println(new Date());
}catch (Exception e){}
}
}
}
4.测试;写个测试类
//异步任务的service
@Autowired
private AsyncTestService asyncTestService;
@GetMapping("testAsync")
public XLBaseResponse<String> testAsync(){
//调用异步任务
this.asyncTestService.forTest();
return XLBaseResponse.newInstance("访问成功!");
}
测试结果:
异步的结果:访问这个controller的方法后,会同步得到响应的结果;但是异步方法中循环打印时间的程序会在响应返回后继续完成自己的执行;
线程:这里用到的ThreadPoolTaskExecutor线程池来处理,因此一些高并发后者有更多其他异步任务的需求,也可以在AsyncTask 中添加更多的方法获取Executor,并指定异步任务名称和线程前缀;
完