spring task定时任务
添加注解 @EnableScheduling
在使用需要定时任务的方法上添加
@Scheduled(cron = "0 0/1 * * * ?") 这里使用了cron表达式
@Scheduled 的参数
1、cron cron表达式
2、zone 设置时区
比如@Scheduled(cron = "0 0/1 * * * ?", zone = "UTC")
zone 时区只对cron表达式有效
3、fixedDelay 任务执行间隔 单位毫秒 long类型
前一个任务执行完成后 后面的任务需要等待相应的时间间隔才能继续执行
fixedDelayString 任务执行间隔 单位毫秒 和fixedDelay一样这里是使用的字符串
@Scheduled(fixedDelayString=“1000”) 1秒执行一次
4、fixedRate 按照一定速率运行 单位毫秒
@Scheduled(fixedRate =5000) 表示5s执行一次任务 如果有一次任务耗时较长30s,则该任务完成后后面的任务会陆续执行尽量保证以每5s每个的速率执行完任务
fixedRateString 和 fixedRate 一样 这里是字符串形式
5、initialDelay 第一次执行延迟的毫秒数
默认使用单线程同步执行 我们可以配置使用多线程异步执行
使用注解 @EnableAsync 开启异步执行
在定时方法上添加@Async即可
/** * 使用spring task 处理定时任务 * 也可以使用 Quartz * 注意默认 spring task 是以单线程运行如果有些任务执行时间过长的话会造成阻塞 * 导致下一次任务延迟执行 这里可以使用@EnableAsync 开启多线程任务 * 在相应的任务方法上添加@async注解即可 * @author 超 * @description * @createDate 2022/3/12 11:51 */ @Component @EnableScheduling @EnableAsync public class ScheduledService { /** * 这里自定义线程池的配置信息 * 如果想使用默认的不需要配置 * @date 2022/3/12 14:26 * @return org.springframework.core.task.TaskExecutor */ @Bean public TaskExecutor taskExecutor(){ ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); taskExecutor.setCorePoolSize(2); taskExecutor.setMaxPoolSize(5); // 非核心线程超过多长时间没有活跃 自动删除 taskExecutor.setKeepAliveSeconds(300); // 阻塞队列的大小 taskExecutor.setQueueCapacity(10000); return taskExecutor; } // 格式 秒 分 时 天 月 星期 年份 /* `*` 字符代表所有可能的值 `/` 字符用来指定数值的增量 比如:(分钟)里的“0/15”表示从第0分钟开始,每15分钟 `?` 字符仅被用于天(月)和天(星期)两个子表达式,表示不指定值 当2个子表达式其中之一被指定了值以后,为了避免冲突,需要将另一个子表达式的值设为? `L` 字符仅被用于天(月)和天(星期)两个子表达式,它是单词“last”的缩写 比如: 3L 指定了月标识 哪个月的最后3天 指定了星期 标识 哪个星期的最后3天 `W` 字符代表着*日(Mon-Fri),并且仅能用于日域中。它用来指定离指定日的最*的一个*日。大部分的商业处理都是基于工作周的,所以W字符可能是非常重要的。 日域中的15W意味着 “离该月15号的最*一个*日。” 假如15号是星期六,那么 trigger 会在14号(星期五)触发,因为星期四比星期一离15号更*。 `C` 代表“Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。 比如 5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于星期日后的第一天 */ @Async @Scheduled(cron = "0 0/1 * * * ?") public void testWork(){ System.out.println(Thread.currentThread().getName() +" 定时任务执行了:" + (LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) - LocalDateTime.of(2022,3,12, 0, 0).toEpochSecond(ZoneOffset.UTC))); } }
2.动态定时任务
实现SchedulingConfigurer 接口
例子
封装的一个抽象类 我们需要实现定时任务,继承该类即可
public abstract class AbsScheduleService implements SchedulingConfigurer { @Resource private TaskScheduler taskScheduler; @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setTaskScheduler(taskScheduler); taskRegistrar.addTriggerTask(this::processTask, triggerContext -> { String cron = getCron(); CronTrigger trigger = new CronTrigger(cron); // 只有一个定时任务的,不会有两个任务一同执行 return trigger.nextExecutionTime(triggerContext); }); } @Bean public TaskScheduler taskScheduler(){ ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); taskScheduler.setPoolSize(2); taskScheduler.setAwaitTerminationSeconds(30); return taskScheduler; } /* 让子类重写 主要用来获取cron表达式 */ public abstract String getCron(); /* 让子类重写 用来具体干活的方法 */ public abstract void processTask(); }
具体使用的类 可以多个 实现多个定时任务
@Component public class TestScheduleService extends AbsScheduleService { @Resource private RedisTemplate<String, String> redisTemplate; @Override protected String getCron() { // 定时任务cron表达式放到数据库中 // 可以动态修改cron表达式 redisTemplate.opsForValue().setIfAbsent("cron", "0/5 * * * * ?"); String cron = redisTemplate.opsForValue().get("cron"); System.out.println("cron修改了:" + cron); return cron; } @Override protected void processTask() { try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();} System.out.println("执行任务了222:" + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
2020-03-31 springboot 方法内部调用注解缓存方法无效的问题