一、什么是Spring Task
Spring Task 是 Spring 框架的一个组件,它为任务调度提供了支持,使得开发者能够创建后台任务或定期执行的任务。通过 Spring Task,您可以方便地在 Java 应用程序中实现定时任务,比如每天凌晨进行数据同步、每小时执行一次清理操作等。
二、开启Spring Task
启动类添加**@EnableScheduling
** 注解,以开启基于注解的任务调度器。默认情况下,系统会自动启动一个线程,调度执行项目中定义的所有定时任务
三、同步定时任务 @Scheduled 定时任务
**在需要定时执行的方法上添加@Scheduled
注解即可。**定时执行的方法不能有参数,并且一般没有返回值,即使有返回值也没什么用;并且要把定时方法所在的类放入IOC容器
3.1**@Scheduled注解的使用**
1.fixedDelay:上次结束到下次开始之间的时间间隔
java
@Scheduled(fixedDelay = 4000)
2.fixedRate:上一次开始执行时间和下次开始时间间隔10s
java
@Scheduled(fixedRate = 10000)
3. initialDelay:第一次延迟多长时间后再执行。
java
@Scheduled(initialDelay=1000, fixedRate=5000)
//第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次
四、异步定时任务(@Async)
4.1开启异步支持
要在 Spring Boot 应用中启用异步方法调用,需在启动类上添加 @EnableAsync
注解。
4.2定义异步方法
在服务类中定义一个方法,并使用 @Async
注解标记它以实现异步执行;
五、自定义线程池
java
@Component
public class ExecutorConfig {
//定义核心线程数
public static final int CORE_POOL_SIZE = 10;
// 最大线程数
public static final int MAX_POOL_SIZE = 20;
// 任务队列容量大小
public static final int QUEUE_MAX_COUNT = 100;
@Bean("asyncScheduledPool")
//放进IOC容器并起名称
public Executor asyncScheduledPool(){
//自定义线程池
ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
//设置核心线程数
threadPoolExecutor.setCorePoolSize(CORE_POOL_SIZE);
//设置最大线程数 : 长工 + 临时工
threadPoolExecutor.setMaxPoolSize(MAX_POOL_SIZE);
//设置任务队列容量大小
threadPoolExecutor.setQueueCapacity(QUEUE_MAX_COUNT);
//设置线程的名称前缀
threadPoolExecutor.setThreadNamePrefix("myTask-");
//设置拒绝策略
threadPoolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
return threadPoolExecutor;
}
}
请注意,阿里并不推荐使用JDK自带的线程池,因为他有一些弊端,不是不让使用,而是使用的时候我们最好能定义一些确切参数
为什么阿里不推荐使用JDK自带线程池
如图:我们可以看到核心线程数,最大线程数,以及最大空闲等待时间,除了图上所示的还有队列,他们设置的值都是Interger.MAX.VALUE,这个值的最大值能达到21亿,也就是说,如果不加管控,就可能一直创建线程达到21亿个,如果内存不足一定会引发OOM(内存溢出)问题
他的缺点有:
1、资源耗尽的风险
2、拒绝策略不明确
3、线程池参数优化
4、监控和调试难度
总结起来,阿里巴巴之所以推荐使用 ThreadPoolExecutor
手动创建线程池,是为了增强系统稳定性,降低资源耗损风险,并提升开发者对线程池行为的控制能力。