在开发过程中避免不了要使用定时任务,例如:定时统计数据,上传数据等等。而springboot的定时任务Scheduled默认是单线程。所以当一个类中需要执行的定时方法过多是,任务就会排队,不按时执行!
下面放上一张截图,这个是每小时的第十分钟执行的一个定时任务:
这是数据入库的时间。
因为定时任务太多,而定时任务又是单线程,导致任务一直排队。所以定时任务就不按时执行。
这时候就需要配置多线程了。
springboot的@Async有默认的线程池,但是不建议使用。
单百度了下,网上提到@Async默认异步配置使用的是SimpleAsyncTaskExecutor,该线程池默认来一个任务创建一个线程,在压测情况下,会有大量写库请求进入日志写库服务,这时就会不断创建大量线程,极有可能压爆服务器内存。导致oom(内存溢出)
所以建议自己创建一个线程池!
可以直接在springboot的启动类中配置线程池。
@EnableScheduling //开启定时任务
@EnableAsync //开启异步任务,开启多线程的关键
@SpringBootApplication
public class ApplicationWeb implements SchedulingConfigurer {
public static void main(String[] args) {
SpringApplication.run(ApplicationWeb.class, args);
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
//设定一个长度15的定时任务线程池
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(15));
}
/**
* 异步线程池设置
* 如果所有的任务都使用异步,线程池执行的话,可以不配置同步任务线程池。但是使用异步需要注意的是异步线程池的大小配置。异步的线程池默认是无上限的开启线程数的。
* @return
*/
@Bean
SimpleAsyncTaskExecutor simpleAsyncTaskExecutor(){
SimpleAsyncTaskExecutor simpleAsyncTaskExecutor = new SimpleAsyncTaskExecutor();
simpleAsyncTaskExecutor.setConcurrencyLimit(7); //设置最大并行数
simpleAsyncTaskExecutor.setDaemon(true); //设置为守护线程
return simpleAsyncTaskExecutor;
}
}
创建过线程池之后,只需要在定时任务的类或者需要开启多线程的方法上添加上@Async注解就可以了。
就像这样: