springboot定时任务配置详解
cron表达式详解
cron表达式是一个字符串,由6或7个表达式组成,每个表达式中间有个空格,每个表达式代表一个含义,cron有如下两种语法格式:
- Seconds(秒) Minutes(分) Hours(时) DayofMonth(月份中的日期) Month(月) DayofWeek(星期中的日期) Year(年)
- Seconds(秒) Minutes(分) Hours(时) DayofMonth(月份中的日期) Month(月) DayofWeek(星期中的日期)
位置顺序 | 表达式名称 | 允许值 | 允许的特殊字符 |
---|---|---|---|
1 | Seconds(秒) | 0-59的整数 | , – * / |
2 | Minutes(分) | 0-59的整数 | , – * / |
3 | Hours(时) | 0-23的整数 | , – * / |
4 | DayofMonth(月份中的日期) | 1-31的整数 | , – * / ? L W C |
5 | Month(月) | 1-12的整数或JAN-DEc | , – * / |
6 | DayofWeek(星期中的日期) | 1-7的整数(1表示星期天,2表示星期一) | , – * / ? L C # |
7 | Year(年)(可选) | 1970-2099年 | , – * / |
每个表达式都可以使用数字,也可以使用特殊字符代替,特殊字符含义如下:
- 星号(*):可用在所有字段中, 表示对应时间表达式的每一个时刻, 例如, 在秒字段时, 表示“每秒”;
- 问号(?):只能用在DayofMonth和DayofWeek两个表达式。因为DayofMonth和DayofWeek这两个元素是互斥的,因此应该通过设置一个问号(?)来表明不想设置的那个字段。
例如想在每月的10日触发任务调度,不管10日到底是星期几,则只能使用如下写法: 0 0 0 10 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,
与在每月10号触发矛盾了。 - 减号(-):表达一个范围,例如在Hours表达式使用8-12,表示从8点到12点每小时触发一次任务
- 逗号(,):表达一个列表值, 如在星期字段中使用“2,3,6”, 则表示星期一, 星期三和星期五;
- 斜杠(/):x/y 表达一个等步长序列, x 为起始值, y 为增量步长值。 如在秒字段中使用 0/15, 则表示为 0,15,30 和 45 秒,都要执行调度任务。
而5/15 在分钟字段使用则表示在5,20,35,50分钟的时候都要执行调度任务。你也可以使用/y, 它等同于 0/y; - L(字母):表示最后,只能出现在DayofWeek和DayofMonth表达式,如果在DayofWeek表达式使用2L,表示在最后的一个星期一触发调度任务;
- W(字母):表示有效工作日(周一到周五),只能出现在DayofMonth表达式,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用10W,如果10号是星期六,则将在最近的工作日:星期五,即14号触发。
如果15号是星期天,则在16号(周一)触发;如果15号在星期一到星期五中的一天,则就在15号当天触发。但必须注意匹配日期不能够跨月, 如你指定1W, 如果1号是星期六, 正确匹配的是 3 号星期一,
而不是上个月最后的那天(星期五)。 W 字符串只能指定单一日期, 而不能指定日期范围; - LW(字母):在DayofMonth表达式可以组合使用 LW, 它的意思是当月的最后一个工作日
- #(字母):用于确定每个月第几个星期几,只能出现在DayofMonth表达式。例如在2#3,表示某月的第三个星期一。
- C(字母): 该字符只在DayofWeek和DayofMonth表达式中使用, 代表“Calendar”的意思。 它的意思是计划所关联的日期,如果日期没有被关联, 则相当于日历中所有日期。
例如 5C 在DayofMonth字段中就相当于日历 5 日以后的第一天。1C 在DayofWeek字段中相当于星期日后的第一天。
::: tip 提示
Cron 表达式对特殊字符的大小写不敏感, 对代表星期的缩写英文大小写也不敏感。
:::
示例:
- @Scheduled(cron=“0/5 * * * * ?”) // 每隔5秒钟执行一次任务
- @Scheduled(cron=“0 0/1 * * * ?”) // 每隔1分钟执行一次任务
- @Scheduled(cron=“0 0 12 * * ?”) // 每天中午12点行一次任务
- @Scheduled(cron=“0 25 10 ? * *”) // 每天上午10:25行一次任务
- @Scheduled(cron=“0 25 10 * * ?”) // 每天上午10:25行一次任务
- @Scheduled(cron=“0 25 10 * * ? *”) // 每天上午10:25行一次任务
- @Scheduled(cron=“0 15 10 * * ? 2005”) // 2005年的每天上午10:15行一次任务
- @Scheduled(cron=“0 * 18 * * ?”) // 在每天下午6点到下午6:59期间的每1分钟行一次任务
- @Scheduled(cron=“0 0/5 18 * * ?”) // 在每天下午6点到下午6:55期间的每5分钟行一次任务
- @Scheduled(cron=“0 0/5 14,18 * * ?”) // 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟
- @Scheduled(cron=“0 0-5 18 * * ?”) // 在每天下午6点到下午6:05期间的每1分钟行一次任务
- @Scheduled(cron=“0 0 8,10,12 * * ?”) // 每天上午8点,10点,12点行一次任务
- @Scheduled(cron=“0 0/30 9-17 * * ?”) // 朝九晚五工作时间内每半小时行一次任务
- @Scheduled(cron=“0 0 12 ? * 2”) // 表示每个星期一中午12点行一次任务
- @Scheduled(cron=“0 10,50 14 ? 2 3”) // 每年二月的星期二的下午2:10和2:50行一次任务
- @Scheduled(cron=“0 20 10 ? * 2-6”) // 周一至周五的上午10:20行一次任务
- @Scheduled(cron=“0 35 10 20 * ?”) // 每月20日上午10:35行一次任务
- @Scheduled(cron=“0 35 10 L * ?”) // 每月最后一日的上午10:35行一次任务
- @Scheduled(cron=“0 35 10 ? * 6L”) // 每月的最后一个星期五上午10:35行一次任务
- @Scheduled(cron=“0 35 10 ? * 6L 2020-2025”) // 2020年至2025年的每月的最后一个星期五上午10:35
- @Scheduled(cron=“0 35 10 ? * 6#2”) // 每月的第二个星期五上午10:35行一次任务
线程池配置详解
@Configuration
public class TaskConfig3 {
//核心线程数,默认是1,为1的时候就是单线程
private int corePoolSize = 5;
//最大线程数,核心线程不够用的时候会创建新的线程,最大不超过maxPoolSize
private int maxPoolSize = 20;
//队列最大长度(容量)
private int queueCapacity = 5;
//非核心线程闲置时的超时时长,单位时秒
private int keepAliveTime = 60;
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//设置核心线程数
executor.setCorePoolSize(corePoolSize);
//设置最大线程数
executor.setMaxPoolSize(maxPoolSize);
//设置队列最大长度(容量)
executor.setQueueCapacity(queueCapacity);
//设置闲置时的超时时长
executor.setKeepAliveSeconds(keepAliveTime);
//允许核心线程超时,默认时false,当设置为true后,核心线程超时也会销毁
executor.setAllowCoreThreadTimeOut(true);
// 线程池对拒绝任务(无线程可用)的处理策略,目前有4种方式,分别如下
// AbortPolicy 丢弃任务,抛运行时异常,CallerRunsPolicy 执行任务
// DiscardPolicy 忽视,什么都不会发生,DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//等待所有线程执行完关闭线程池,默认为false
executor.setWaitForTasksToCompleteOnShutdown(true);
//设置等待关闭线程池的时间,因为不能无限的等待下去
executor.setAwaitTerminationSeconds(60);
//设置线程名字的前缀
executor.setThreadNamePrefix("test-task-");
executor.initialize();
return executor;
}
}
corePoolSize
:核心线程数。
- 核心线程会一直存活,及时没有任务需要执行
- 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理
- 设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭
maxPoolSize
:最大线程数。
- 当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务
- 当线程数=maxPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常或根据
RejectedExecutionHandler
来进行拒绝策略处理。
queueCapacity
:任务队列容量(阻塞队列)
+当核心线程数达到最大时,新任务会放在队列中排队等待执行keepAliveTime
:线程空闲时间
- 当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize
- 如果allowCoreThreadTimeout=true,则会直到线程数量=0
- allowCoreThreadTimeout:允许核心线程超时
- rejectedExecutionHandler:任务拒绝处理器
- 两种情况会拒绝处理任务:
- 当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务
- 当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务
- 线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常
- ThreadPoolExecutor类有几个内部实现类来处理这类情况:
- AbortPolicy 丢弃任务,抛运行时异常
- CallerRunsPolicy 执行任务
- DiscardPolicy 忽视,什么都不会发生
- DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
- 实现RejectedExecutionHandler接口,可自定义处理器
默认值
- corePoolSize=1
- queueCapacity=Integer.MAX_VALUE
- maxPoolSize=Integer.MAX_VALUE
- keepAliveTime=60s
- allowCoreThreadTimeout=false
- rejectedExecutionHandler=AbortPolicy()
1介绍
2springboot定时任务
3springboot定时任务配置详解
4springboot动态定时任务
5springboot集成websocket
6springboot多数据源
7springboot配置druid监听
8springboot自定义注解
9springboot常见注解详解
10springboot接收参数详解
11springboot验证机制@Valid和@Validated
12springboot集成Swagger2
13springboot集成swagger-bootstrap-ui
14springboot集成shiro
15springboot集成shiro(二)
16springboot集成jwt
17springboot集成ActiveMQ
18springboot缓存机制
🍉🍉🍉 欢迎大家来博客了解更多内容:java乐园 🍉🍉🍉
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/13513.html