浅谈Spring定时任务


三种定时任务基于原理

SpringBoot配置定时任务主要有Spring Schedule、JDK自带的TimeTask以及第三方的quartz框架

  • SpringBoot开启一个定时任务,主要分为以下两步:
  1. 需要执行定时任务方法上加@Scheduled注解
  2. 配置@EnableScheduling开启定时任务。其中@Scheduled注解可以配置fixedRate固定频率执行(若超时,则在当前方法执行完成后立即执行)、fixedDelay固定间隔执行(从上次任务结束时间算)以及自定义cron表达式。Spring Schedule默认会创建一个单线程池执行定时任务(Spring会搜索相关的线程池定义,要么在上下文中搜索唯一的TaskExecutor bean,要么搜索名为“taskExecutor”的Executor bean,如果两者都无法解析,则将使用SimpleAsyncTaskExecutor来处理异步方法调用)当需要多个任务并发(或需要在同一时间)执行,任务调度器就会出现时间漂移,因此通常需要给定时任务自定义配置一个线程池ThreadPoolTaskScheduler
  • TimeTask是按照任务下个执行时间进行堆排序,每次取堆中的最小时间和当前系统时间进行比较,若当前时间大于下个任务执行时间则执行,将任务从最小堆中移除因此Timer定时任务是单线程+堆排序+轮询,并不适合多任务的管理
  • quartz可以通过cron表达式精确到特定时间执行,每次执行任务都会创建一个新的任务类对象而且抛出异常不会影响下次任务执行,但Timer抛出异常整个定时器生命周期就会结束,quartz支持持久化、事务管理以及集群模式对多定时任务调度管理具有一定优势


多定时任务并发配置

Spring Schedule配置多定时任务并发,一般需要自定义配置线程池,主要有两种方式

  • 第一种方式,使用时需要@Async(“指定线程池”)
 @Configuration
 @EnableAsync
 public class ThreadPoolTaskConfig {

     	private static final int corePoolSize = 10;       		// 核心线程数(默认线程数)
     	private static final int maxPoolSize = 100;			    // 最大线程数
     	private static final int keepAliveTime = 10;			// 允许线程空闲时间(单位:默认为秒)
     	private static final int queueCapacity = 200;			// 缓冲队列数
     	private static final String threadNamePrefix = "Async-Service-"; // 线程池名前缀
     	
     	@Bean("taskExecutor") // bean的名称,默认为首字母小写的方法名
     	public ThreadPoolTaskExecutor getAsyncExecutor(){
     		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
     		executor.setCorePoolSize(corePoolSize);   
     		executor.setMaxPoolSize(maxPoolSize);
     		executor.setQueueCapacity(queueCapacity);
     		executor.setKeepAliveSeconds(keepAliveTime);
     		executor.setThreadNamePrefix(threadNamePrefix);
     		
     		// 线程池对拒绝任务的处理策略
     		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
     		// 初始化
     		executor.initialize();
     		return executor;
     	}
     }
  • 第二种方式,直接实现AsyncConfigurer接口,重写getAsyncExecutor方法即可
@Configuration
@EnableAsync
public class AppConfig implements AsyncConfigurer {

     @Override
     public Executor getAsyncExecutor() {
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
         executor.setCorePoolSize(7);
         executor.setMaxPoolSize(42);
         executor.setQueueCapacity(11);
         executor.setThreadNamePrefix("MyExecutor-");
         executor.initialize();
         return executor;
     }

     @Override
     public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
         return new MyAsyncUncaughtExceptionHandler();
     }
}


动态定时任务


定时任务Demo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值