spring boot定时任务总结和实现

介绍

定时任务是程序开发中重要且不可缺少的功能,它会自动按照设定好的时间规则,按时完成执行任务,一般周期性更新数据状态,闲时缓存数据,执行计划任务。
本次主要介绍spring scheduled

种类

  • 定时任务调度的,一般有3种。
    • Timer:java自带定时任务类,单线程执行,适合轻度
    • scheduled:spring 官方定时任务调度,配置简单,支持多线程,通过注解设置,支持cron时间格式。
    • quartz:功能强大的定时任务调度框架,支持分布式,可动态实现任务调度加载。

cron时间规则

  • Cron表达式由6或7个空格分隔的时间字段组成:秒 分钟 小时 日期 月份 星期 年(可选)
字段  允许值  允许的特殊字符 
秒       0-59     , - * / 
分       0-59     , - * / 
小时      0-23     , - * / 
日期      1-31     , - * ? / L W C 
月份      1-12     , - * / 
星期      1-7       , - * ? / L C # 
年     1970-2099   , - * /

使用

简单任务

  • 通过@EnableScheduling开启定时任务调度。
package com.cn.web.common;

@Component //添加注入
@EnableScheduling  //开启定时任务 
public class ServiceScheduleTask {
    
    
	
	private static final Logger log = LoggerFactory.getLogger(ServiceScheduleTask.class);

	
	@Scheduled(cron = "0/10 * * * * ?")  //10秒执行一次
	public void getHostService() {
    
    
		log.info("执行定时任务")
	}
	
	
}

动态时间

  • mysql数据库创建时间规则表,创建crontTest数据库和cron表,3个字段id值、任务名和cron规则。
DROP DATABASE IF EXISTS `cronTest`;
CREATE DATABASE `cronTest`;
USE `cronTest`;
DROP TABLE IF EXISTS `cron`;
CREATE TABLE `cron`  (
  `cron_id` varchar(30) NOT NULL PRIMARY KEY,
  `cron_name` varchar(30) NOT NULL,
  `cron` varchar(30) NOT NULL  
);
INSERT INTO `cron` VALUES ('1', '0/5 * * * * ?');
  • java代码
package com.cn.web.common;

@Component
@EnableScheduling   // 开启定时任务
public class DynamicScheduleTask implements SchedulingConfigurer {
    
    

    private static final Logger log = LoggerFactory.getLogger(DynamicScheduleTask.class);
    //定义mybatis接口
    @Mapper
    public interface CronMapper {
    
    
        @Select("select cron from cron ")
        public Cron getCron();
    }

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

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

        taskRegistrar.addTriggerTask(
                //1.添加任务内容(Runnable)
                () -> log.info("执行动态定时任务: " + LocalDateTime.now().toLocalTime()),
                //2.设置执行周期(Trigger)
                triggerContext -> {
    
    
                    //2.1 从数据库获取执行周期
                    Cron cron = cronMapper.getCron();
                    //2.2 合法性校验.
                    if (StringUtils.isEmpty(cron.getCronName())) {
    
    
                        if(cron.getCronName().equals("task1")){
    
    
                            //任务一,时间周期为cron.getCront()

                        }else if(cron.getCronName().equals("task2")){
    
    
                            //任务二,时间周期为cron.getCront()
                        }
                    }
                    //2.3 返回执行周期(Date)
                    return new CronTrigger(cron).nextExecutionTime(triggerContext);
                }
        );
    }

}
  • 如果想实现复杂任务调度,可在通过反射实现多任务功能配置和调度。

开启多线程

  • 多线程开启增加注解@EnableAsync开启多线程
package com.cn.web.common;

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

    private static final Logger log = LoggerFactory.getLogger(MultithreadScheduleTask.class);

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

    @Async
    @Scheduled(fixedDelay = 2000)
    public void second() {
    
    
        log.info("第二个定时任务开始时间 :{} 线程名:{} " ,LocalDateTime.now().toLocalTime() ,Thread.currentThread().getName());
    }
}

总结

  • spring boot简单任务建议使用spring自带scheduled,复杂或大量任务建议使用quartz。

参考资料

猜你喜欢

转载自blog.csdn.net/qq_22973811/article/details/111032120