美文网首页Spring Boot 核心思想
SpringBoot-定时任务Schedule

SpringBoot-定时任务Schedule

作者: 草莓君_ | 来源:发表于2019-07-29 17:33 被阅读0次

很多小伙伴在实际开发中,一定碰到过需要定时去执行某些业务逻辑的时候,解决方案有很多,比如MQ。不过在这里博主介绍的是springboot提供的比较好用的定时任务组件Scheduled。

大家都知道spring创建定时任务so esay,下面有三种方式:

  • 基于注解 (@Scheduled)
  • 基于接口 (SchedulingConfigurer)
  • 基于注解设定多线程定时任务

一、基于注解 (@Scheduled)

需要注意的是@Scheduled默认是串行的,单线程,当开启多个任务时,任务的执行时机会受上一个任务执行时间的影响。

@Configuration
@EnableScheduling    //开启定时任务
public class ScheduleTask {
    //每10秒执行一次
    @Scheduled(cron = "0/10 * * * * ?")
    private void configureTasks() {
        System.out.println("我是一个定时任务");
    }
}

@Scheduled 除了cron还提供另外三种种方式: fixedRate,fixedDelay,initialDelay
1、cron表达式可以定制化执行任务,但是执行的方式是与fixedDelay相近的,也是会按照上一次方法结束时间开始算起。
2、fixedDelay控制方法执行的间隔时间,是以上一次方法执行完开始算起,如上一次方法执行阻塞住了,那么直到上一次执行完,并间隔给定的时间后,执行下一次。

@Configuration
@EnableScheduling    //开启定时任务
public class ScheduleTask {
    //每10秒执行一次
    @Scheduled(fixedDelay = 10000)
    private void configureTasks() {
        System.out.println("我是一个定时任务");
    }
}

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

@Configuration
@EnableScheduling    //开启定时任务
public class ScheduleTask {
    //每10秒执行一次
    @Scheduled(fixedRate = 10000)
    private void configureTasks() {
        System.out.println("我是一个定时任务");
    }
}

4、initialDelay = 10000 表示在容器启动后,延迟10秒后再执行一次定时器。

@Configuration
@EnableScheduling    //开启定时任务
public class ScheduleTask {
    //容器启动后,延迟10秒后再执行一次定时器,以后每10秒再执行一次该定时器。
    @Scheduled(initialDelay = 10000, fixedRate = 10000)
    private void configureTasks() {
        System.out.println("我是一个定时任务");
    }
}

二、基于接口 (SchedulingConfigurer)

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

  • 下面案例从数据中获取执行周期时间,然后动态执行定时任务:
@Configuration      
@EnableScheduling   //开启定时任务
public class DynamicScheduleTask implements SchedulingConfigurer {

    //从数据获取任务执行周期
    @Autowired
    private MyBatisMapper myBatisMapper;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(
                //1.添加任务内容(Runnable)
                () -> System.out.println("执行动态定时任务: " + LocalDateTime.now().toLocalTime()),
                //2.设置执行周期(Trigger)
                triggerContext -> {
                    //2.1从数据库获取执行周期
                    String cron = myBatisMapper.getCron();
                    //2.2 返回执行周期(Date)
                    return new CronTrigger(cron).nextExecutionTime(triggerContext);
                }
        );
    }
}

数据库表数据如下:

在数据库表中插入时间周期.png

好,我们启动测试看看

执行动态定时任务: 17:17:00.008999
执行动态定时任务: 17:17:20.002501
执行动态定时任务: 17:17:30.001786
执行动态定时任务: 17:17:40.005512
执行动态定时任务: 17:17:50.005870
执行动态定时任务: 17:18:00.002189
执行动态定时任务: 17:18:10.001910

我们可以看到每10秒执行一次任务。那么现在要求每5秒执行一次,该怎么做呢?这个时候我们只需要修改下数据库数据即可,无需重启。


修改数据为5秒每次.png

OK,我们再看看控制台打印的是什么?

执行动态定时任务: 17:18:30.000902
执行动态定时任务: 17:18:40.001392
执行动态定时任务: 17:18:45.005027
执行动态定时任务: 17:18:50.001367
执行动态定时任务: 17:18:55.001356
执行动态定时任务: 17:19:00.001582
执行动态定时任务: 17:19:05.005676
执行动态定时任务: 17:19:10.001258
执行动态定时任务: 17:19:15.005272

成功每5秒执行一次。是不是很嗨~

三、基于注解设定多线程定时任务

前面讲到了@Scheduled执行周期任务会受到上次一个任务的执行时间影响。那么可以开启多线程执行周期任务。

@EnableScheduling   // 1.开启定时任务
@EnableAsync        // 2.开启多线程
@Component
public class MultiThreadScheduleTask {

    @Async
    @Scheduled(fixedDelay = 1000)  //间隔1秒
    public void first() throws InterruptedException {
        System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
        Thread.sleep(1000 * 10);
    }

    @Async
    @Scheduled(fixedDelay = 2000)
    public void second() {
        System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
    }
}

我们重启下项目看看控制台输出什么:

第二个定时任务开始 : 17:27:01.024288
线程 : task-4
第一个定时任务开始 : 17:27:01.024393
线程 : task-7
第一个定时任务开始 : 17:27:02.027932
线程 : task-4
第二个定时任务开始 : 17:27:05.021294
线程 : task-1
第一个定时任务开始 : 17:27:05.021533
线程 : task-1
第一个定时任务开始 : 17:27:06.014213

看,由于开启了多线程,第一个任务的执行时间也不受其本身执行时间的限制。两个任务也互不影响。

相关文章

  • SpringBoot-定时任务Schedule

    很多小伙伴在实际开发中,一定碰到过需要定时去执行某些业务逻辑的时候,解决方案有很多,比如MQ。不过在这里博主介绍的...

  • Nodejs定时任务(node-schedule)

    Nodejs定时任务(node-schedule) 安装 npm install node-schedule --...

  • SpringBoot系列:Spring Boot定时任务Spri

    Spring Schedule是Spring提供的定时任务框架,相较于Quartz,Schedule更加简单易用,...

  • spring boot 2 定时任务

    任务执行 说明@EnableScheduling 开启定时任务@EnableAsync 开启异步@Schedule...

  • Schedule(定时任务)

    概述 虽然定时任务可以嵌⼊到web应⽤程序和WAR⽂件中,但下⾯演⽰⼀种更简单的⽅法创建了⼀个独⽴的应⽤程序。您将...

  • Schedule(定时任务)

    虽然定时任务可以嵌⼊到web应⽤程序和WAR⽂件中,但下⾯演⽰⼀种更简单的⽅法创建了⼀个独⽴的应⽤程序。您将所有的...

  • Spring Schedule定时关单

    目录 1. Spring Schedule介绍 作业调度,如定时任务 2. Spring Schedule Cr...

  • @Schedule

    @Schedule Spring Boot Web依赖中中包含了定时任务 启动定时任务 启动定时任务的关键是在启动...

  • Laravel定时任务Schedule2018-10-26

    爱漂泊人生 PHP Laravel定时任务Schedule 前提:本文方法是利用Linux的crontab定时任务...

  • Spring整合Schedule定时任务详解

    Spring整合Schedule定时任务详解 Spring 定时任务官方网站 一、概述 用Spring,就是为了简...

网友评论

    本文标题:SpringBoot-定时任务Schedule

    本文链接:https://www.haomeiwen.com/subject/unudrctx.html