SpringBoot定时任务


一、基于注解@Scheduled

@Configuration      //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class ScheduledTask {

    // 0/5 * * * * ?表示每隔5秒执行一次这个方法
    @Scheduled(cron = "0/5 * * * * ?")
    public void task1() {
        System.out.println("task1执行了..");
    }

    //在每天凌晨1点,把前一天数据进行数据查询添加
    @Scheduled(cron = "0 0 1 * * ?")
    public void task2() {
       System.out.println("task2执行了..");
    }

    //每隔5000毫秒执行一次
    @Scheduled(fixedDelay = 5000) 
    public void task1() {
        System.out.println("task3执行了..");
    }
}

@Scheduled参数详解

1、cron

该参数接收一个cron表达式cron表达式是一个字符串,字符串以5个空格隔开,分开共6个域,每一个域代表一个含义。秒、分、时、日、月、周。

springboot的@Cheduled不支持第七个域的配置,所以只写6个即可。

cron表达式生成可通过在线生成工具生成:

https://www.pppet.net/

2. zone

时区,接收一个java.util.TimeZone#IDcron表达式会基于该时区解析。默认是一个空字符串,即取服务器所在地的时区。比如我们一般使用的时区Asia/Shanghai。该字段我们一般留空。

3. fixedDelay

每隔多少毫秒执行一次

@Scheduled(fixedDelay = 5000)

4. fixedDelayString

3. fixedDelay 意思相同,只是使用字符串的形式。唯一不同的是支持占位符。如:

占位符的使用(配置文件中有配置:time.fixedDelay=5000):

 @Scheduled(fixedDelayString = "${time.fixedDelay}")

5. fixedRate

上一次开始执行时间点之后多长时间再执行。如:

Copy@Scheduled(fixedRate = 5000) //上一次开始执行时间点之后5秒再执行

fixedRate 的间隔是两次执行时间的开始点,而 fixedDelay 的间隔是前次任务的结束与下次任务的开始。

6. fixedRateString

5. fixedRate 意思相同,只是使用字符串的形式。唯一不同的是支持占位符。

7. initialDelay

第一次延迟多长时间后再执行。如:

Copy@Scheduled(initialDelay=1000, fixedRate=5000) //第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次

8. initialDelayString

initialDelay意思相同,只是使用字符串的形式。唯一不同的是支持占位符。

二、基于接口@SchedulingConfigurer

优点:方便在实际应用中随时修改定时规则(通过修改数据库中的cron表达式实现)

需导入MySql相关依赖,在本地数据库中创建’cron’,专门存放定时任务的表,然后在yml中添加数据源。

DROP DATABASE IF EXISTS `socks`;
CREATE DATABASE `socks`;
USE `SOCKS`;
DROP TABLE IF EXISTS `cron`;
CREATE TABLE `cron`  (
  `cron_id` varchar(30) NOT NULL PRIMARY KEY,
  `cron` varchar(30) NOT NULL  
);
INSERT INTO `cron` VALUES ('1', '0/5 * * * * ?');
@Configuration      //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class DynamicScheduleTask implements SchedulingConfigurer {

    @Mapper
    public interface CronMapper {
        @Select("select cron from cron limit 1")
        public String getCron();
    }

    @Autowired      //注入mapper
    @SuppressWarnings("all")
    CronMapper cronMapper;

    /**
     * 执行定时任务.
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

        taskRegistrar.addTriggerTask(
                //1.添加任务内容(Runnable)
                () -> System.out.println("执行动态定时任务: " + LocalDateTime.now().toLocalTime()),
                //2.设置执行周期(Trigger)
                triggerContext -> {
                    //2.1 从数据库获取执行周期
                    String cron = cronMapper.getCron();
                    //2.2 合法性校验.
                    if (StringUtils.isEmpty(cron)) {
                        // Omitted Code ..
                    }
                    //2.3 返回执行周期(Date)
                    return new CronTrigger(cron).nextExecutionTime(triggerContext);
                }
        );
    }

}

三、多线程定时任务

使用@Async结合注解设定多线程定时任务

//@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();
        }
    }

  目录