SpringBoot SpringBoot 定时器的三种方式定时器的三种方式
原文地址:https://blog.csdn.net/qq_37657093/article/details/122704647
SpringBoot 使用定时器的3种方式
1、使用@Scheduled注解定义
@Component public class SimpleSchedule { private Integer time = 0; @Scheduled(cron = "*/6 * * * * ?") //定时器定义,设置执行时间 private void process() { System.out.println("定时器1执行"+time++); } @Scheduled(fixedDelay = 1*1000) //定时器定义,设置执行时间 1s private void process1() { System.out.println("定时器2执行"+time++); } }
需要在添加注解 @EnableScheduling 来扫描定时器并执行:
@EnableScheduling //扫描定时器 @SpringBootApplication public class ScheduleDemoApplication { public static void main(String[] args) { SpringApplication.run(ScheduleDemoApplication.class, args); } }
@Scheduled 中的属性有如下几种:
cron表达式:指定任务在特定时间执行 fixedDelay:表示上一次任务执行完成后多久再执行,参数类型long,单位:ms fixedDelayString:与fixedDelay一样,只是参数类型是String fixedRate:表示按一定的频率执行任务,参数类型long,单位:ms 如: fixedRate(5000),表示这个定时器任务每5秒执行一次 fixedRateString:与fixedRate一样,只是参数类型变为String initialDelay:表示延迟多久再第一次执行任务,参数类型为long ,单位:ms initialDelayString:与initialDelay一样,只是参数类型String
其中corn表达式的格式举例如下:
0 0 10,14,16 * * ? 每天上午10点,下午2点,4点 0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时 0 0 12 ? * WED 表示每个星期三中午12点 0 0 12 * * ? 每天中午12点触发 0 15 10 ? * * 每天上午10:15触发 0 15 10 * * ? 每天上午10:15触发 0 15 10 * * ? * 每天上午10:15触发 0 15 10 * * ? 2005 2005年的每天上午10:15触发 0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发 0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发 0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发 0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发 0 15 10 ? * MON-FRI 周一至周五的上午10:15触发 0 15 10 15 * ? 每月15日上午10:15触发 0 15 10 L * ? 每月最后一日的上午10:15触发 0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发 0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发 0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发
2、使用多线程执行定时器
该种定时器的执行是在方法被调用的时候按照设置的时间执行一次。
举例如下:
1)定义线程池(使用 @EnableAsync 开启异步事件的支持)
@Configuration @EnableAsync public class AsyConfig { /* 此处成员变量应该使用@Value从配置中读取 */ private int corePoolSize = 10; private int maxPoolSize = 200; private int queueCapacity = 10; private Integer time = 0; @Bean("taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(queueCapacity); executor.initialize(); return executor; } }
2)使用线程池定义需要执行的任务(使用@Service标注对应的类,使用@Async 开启线程支持 ,“taskExecutor” 为线程bean 的ID)
@Service public class TestAsync { Logger log = LoggerFactory.getLogger(TestAsync.class); @Async("taskExecutor") @Scheduled(cron = "*/10 * * * * ?") public void service1() throws InterruptedException { log.info("--------start-service1------------"); Thread.sleep(5000); // 模拟耗时 log.info("--------end-service1------------"); } @Async("taskExecutor") @Scheduled(cron = "*/5 * * * * ?") public void service2() throws InterruptedException { log.info("--------start-service2------------"); Thread.sleep(2000); // 模拟耗时 log.info("--------end-service2------------"); } }
3)调用第2步定义的任务
@RestController public class TestController { @Autowired private TestAsync testAsync; @GetMapping("/") public void test(){ try { testAsync.service1(); } catch (InterruptedException e) { e.printStackTrace(); } } }
4)重启服务测试
3、使用 ScheduledTaskRegistrar 实现可配置化的定时任务
1)自定义CompleteScheduleConfig 继承 SchedulingConfigurer
注意:需要添加 @Component 注解
@Component public class CompleteScheduleConfig implements SchedulingConfigurer { /** * 执行定时任务. */ @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { //设置corn表达式,后续配置在数据库中查询出来 String cron = "*/6 * * * * ?"; taskRegistrar.addTriggerTask( //1.添加任务内容(Runnable) ()->{ System.out.println("定时任务执行,时间为 :"+LocalDateTime.now().toLocalTime()); }, //2.设置定时时间 triggerContext -> { //2.2 合法性校验. if (cron!=null) { //填写异常处理代码 } //2.3 返回执行周期(Date) return new CronTrigger(cron).nextExecutionTime(triggerContext); } ); }