🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
#### 基于注解 基于注解@Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的影响。 使用SpringBoot基于注解来创建定时任务非常简单,只需几行代码便可完成。 代码如下: ``` @Component @Configuration //1.主要用于标记配置类,兼备Component的效果。 @EnableScheduling // 2.开启定时任务 public class SaticScheduleTask { //3.添加定时任务 @Scheduled(cron = "0/5 * * * * ?") //或直接指定时间间隔,例如:5秒 //@Scheduled(fixedRate=5000) private void configureTasks() { System.err.println("执行静态定时任务时间: " + LocalDateTime.now()); } } ``` #### 1、@Scheduled(fixedDelay = 5000) 将以一个固定延迟时间5秒钟调用一次执行,这个周期是以上一个调用任务的完成时间为基准,在上一个任务完成之后,5s后再次执行。 #### 2、@Scheduled(fixedRate = 5000) 将以一个固定速率5s来调用一次执行,这个周期是以上一个任务开始时间为基准,从上一任务开始执行后5s再次调用。 #### 3、cron表达式 @Scheduled(cron = "0 */60 * * * ?")//每1小时(60分钟)执行一次 ``` "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触发 ``` #### 多个定时任务冲突、不执行,增加定时任务线程数 ``` spring的定时任务默认是单线程,多个任务执行起来时间会有问题:B任务会因为A任务执行起来需要20S而被延后20S执行,需要增加定时任务配置,配置定时任务连接池大小。 SpringBoot解决方案: import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import java.util.concurrent.Executors; @Configuration public class ScheduleConfig implements SchedulingConfigurer{ @Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { //参数传入一个size为10的线程池 scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(10)); } } SSM框架解决方案: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/beans classpath:/org/springframework/beans/factory/xml/spring-beans-4.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd"> <!-- 注解式 --> <task:annotation-driven executor="taskExecutor" proxy-target-class="true" scheduler="scheduler" /> <!-- 配置处理定时任务的线程池 --> <task:scheduler id="myScheduler" pool-size="5" /> <!-- 配置处理 异步定时任务的 线程池 --> <beans:bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <!-- 核心线程数 --> <beans:property name="corePoolSize" value="5" /> <!-- 最大线程数 --> <beans:property name="maxPoolSize" value="10" /> <!-- 队列最大长度 --> <beans:property name="queueCapacity" value="25" /> <!-- 线程池维护线程所允许的空闲时间,默认为60s --> <beans:property name="keepAliveSeconds" value="300" /> <!-- 线程池对拒绝任务(无线程可用)的处理策略 ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃. --> <beans:property name="rejectedExecutionHandler"> <beans:bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /> </beans:property> </beans:bean> </beans> ```