SpringBoot定时任务的实现

tech2023-02-20  112

定时任务

一、静态,基于注解(@Scheduled)二、动态,基于接口SchedulingConfigurer 自定义时间动态执行定时任务三、基于注解设定多线程定时任务(未试过)引用:

使用SpringBoot创建定时任务非常简单,目前主要有以下三种创建方式:

一、静态,基于注解(@Scheduled)

基于注解@Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的影响。

1、创建定时器

使用SpringBoot基于注解来创建定时任务非常简单,只需几行代码便可完成。 代码如下:

@Configuration//主要用于标记配置类,兼备Component的效果。 @EnableScheduling//开启定时任务 public class schedule { @Scheduled(cron = "0/5 * * * * ?")//添加定时任务 //或直接指定时间间隔,例如:5秒 //@Scheduled(fixedRate=1000) private void configureTasks() { System.err.println("执行静态定时任务时间: " + LocalDateTime.now()); } }

Cron表达式参数分别表示:

秒(0~59) 例如0/5表示每5秒分(0~59)时(0~23)日(0~31)的某天,需计算月(0~11)周几( 可填1-7 或 SUN/MON/TUE/WED/THU/FRI/SAT)

@Scheduled注解可以控制方法定时执行,其中有三个参数可选择:

1、fixedDelay控制方法执行的间隔时间,是以上一次方法执行完开始算起,如上一次方法执行阻塞住了,那么直到上一次执行完,并间隔给定的时间后,执行下一次。

2、fixedRate是按照一定的速率执行,是从上一次方法执行开始的时间算起,如果上一次方法阻塞住了,下一次也是不会执行,但是在阻塞这段时间内累计应该执行的次数,当不再阻塞时,一下子把这些全部执行掉,而后再按照固定速率继续执行。

3、cron表达式可以定制化执行任务,但是执行的方式是与fixedDelay相近的,也是会按照上一次方法结束时间开始算起。

4、initialDelay 。如: @Scheduled(initialDelay = 10000,fixedRate = 15000 这个定时器就是在上一个的基础上加了一个initialDelay = 10000 意思就是在容器启动后,延迟10秒后再执行一次定时器,以后每15秒再执行一次该定时器。

显然,使用@Scheduled 注解很方便,但缺点是当我们调整了执行周期的时候,需要重启应用才能生效,这多少有些不方便。为了达到实时生效的效果,可以使用接口来完成定时任务。

二、动态,基于接口SchedulingConfigurer 自定义时间动态执行定时任务
@Configuration //1.主要用于标记配置类,兼备Component的效果 @EnableScheduling//开启定时任务 public class WorkstationSchedule implements SchedulingConfigurer {//会提示需要重写一个方法 @Autowired FileMapper fileMapper; @Autowired insertWorkstationIntoMysql insertWorkstationIntoMysql; @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.addTriggerTask( //1.添加任务内容(Runnable) () -> insertWorkstationIntoMysql.hhh(),//执行定义的方法 //2.设置执行周期(Trigger) triggerContext -> { //2.1 从数据库获取执行周期 String cron = fileMapper.findSchedule("001"); //2.2 合法性校验. if (StringUtils.isEmpty(cron)) { // Omitted Code .. } //2.3 返回执行周期(Date) return new CronTrigger(cron).nextExecutionTime(triggerContext); } ); } }
三、基于注解设定多线程定时任务(未试过)
//@Component注解用于对那些比较中立的类进行注释; //相对与在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释 @Component @EnableScheduling // 1.开启定时任务 @EnableAsync // 2.开启多线程 public class MultithreadScheduleTask { @Async @Scheduled(fixedDelay = 1000) //间隔1秒 public void first() throws InterruptedException { System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName()); System.out.println(); Thread.sleep(1000 * 10); } @Async @Scheduled(fixedDelay = 2000) public void second() { System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName()); System.out.println(); } }

从控制台可以看出,第一个定时任务和第二个定时任务互不影响;

并且,由于开启了多线程,第一个任务的执行时间也不受其本身执行时间的限制,所以需要注意可能会出现重复操作导致数据异常。

引用:

https://www.cnblogs.com/mmzs/p/10161936.html

https://blog.csdn.net/qq_34129814/article/details/85090162

最新回复(0)