今天和大家分享下Spring Task这个知识点,主要通过下面6个点来展开描述,希望能够帮助到大家。
1、什么是定时任务
2、入门案例
3、Corn表达式
4、Corn实战案例
5、@Scheduled
6、多线程任务
1、什么是定时任务
定时任务是系统在特定时间执行一段代码。
定时任务的实现主要有以下几种方式:
- Java自带的java.util.Timer类。它允许调度一个java.util.TimerTask任务,使用这种方式可以让程序按照某一个频度执行,但不能在指定时间运行,一般运用较少。
- Quartz。是一个功能比较强大的调度器,可以让程序在执行时间执行,也可以按照某个频度执行,配置起来有点复杂。
- Spring3.0以后自带Spring Task。可以看成一个轻量级的Quartz,
2、入门案例
1、创建SpringBoot项目在启动类开启定时任务@EnableScheduling
@SpringBootApplication
@EnableScheduling
public class SpringtaskdemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringtaskdemoApplication.class, args);
}
}
//每秒都执行一次
@Scheduled(cron = "* * * * * *")
public void test(){
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
System.out.println(format.format(new Date()));
}
3、Corn表达式
Spring Task 依靠Corn表达式配置定时规则,Corn表达式是一个字符串,分为6或7个域。每个域代表一个含义,以空格隔开,有如下两种语法格式:
1、秒 分 时 每月第几天 月份 周几 年份
2、秒 分 时 每月第几天 月份 周几
3.1 秒
Seconds(秒)域可以出现,- * /
和0-59
的整数
-
*:表示匹配该域的任意值,在Seconds域中使用 * 表示每秒钟都会出发
-
,:表示列出枚举值,在Seconds域中使用5,20表示在5秒和20秒各触发一次
-
-:表示范围,在secondes域使用5-20,表示从5秒到20秒每秒触发一次
-
/:表示起始时间开始触发,然后每隔固定时间触发一次,在secondes域中使用5/20,表示第5秒触发一次,25秒、45秒各触发一次。
3.2 分、时
以上四个字符在minutes和Hours域都可以出现。分钟整数为0-59,小时整数为0-23
3.3 日期
DayofMonty(日期):域中可以出现,- * / ? L W C 八个字符,以及1-31的整数。
- c:表示和当前日期相关联,如果在该域使用
5c
,则在执行当天的5日后执行,且每月的那天都会执行。比如执行日是10号,则每月的15号都会触发。 - L:表示最后,在该域使用L,表示每月的最后一天触发;
- W:表示工作日,在该域用15W,表示在最接近本月第15天的工作日出发,如果15号是周六则14号触发,如果15号是周日则16号出发,如果15号是周二,则15号触发。 注:该用法只会在当前月计算,不会到下月触发,比如在DayofMonth域用31W,31号是周日,那么在29号触发,而不是下月1号。
- 在DayofMonth域用LW,表示这个月的最后一个工作日触发。
3.4 月份
Month(月份):域中可出现,- * /
四个字符,以及1-12的整数或JAN-DEC的单词缩写
3.5 星期
DayofWeek(星期):可出现,- * / ? L # C
八个字符,以及1-7的整数或SUN-SAT单词的缩写,1代表星期天,7代表周六
- c:在DayofWeek域使用2c,表示在启动日后的2天后触发,且每周的那天都会触发,如在周一启动,那么每周三都会触发;
- L:L表示一周的最后一天(周六)触发,如果使用
5L
,表示在一个月的最后一个周四触发 -
:用来执行具体的周数,#前面代表星期几,#后面代表一个月的第几周。如
5#3
表示一个月第三周的星期四 - ?:在无法确定是哪一天时使用。用于DayofMonth和DayofWeek域。如每个21号零点触发1次,此时无法确定21号是周几,就写
0 0 0 21 * ?
3.6 年份
Year(年份):,- * /
四个字符,以及 1970~2099的整肃,该域可以省略,表示每年都会触发。
4、Corn实战案例
每间隔5分钟触发一次 :0 0/5 * * * *
每小时触发一次 0 0 * * * *
每天7:30触发 0 30 7 * * *
每周一到周五早上6:30触发 0 30 6 ? * 2-6
每月最后一天早上10点触发 0 0 10 L * ?
每月最后一个工作日的18:30分触发 0 30 18 LW * ?
2030年8月每个星期六和星期日早上10触发 0 0 10 ? 8 7,1 2030
每天10点、12点、14点触发 0 0 10,12,14 * * *
朝九晚五工作日内每半小时触发一次 0 0/30 9-17 W * ?
每周三中午12点触发一次 0 0 12 ? * 4
每天12点触发一次 0 0 12 * * *
每天14点到14:59每分钟触发一次 0 * 14 * * *
每天14点到14:59每5分钟触发一次 0 0/5 14 * * *
每天14点到14:05每分钟触发一次 0 0-5 14 * * *
每月15日上午10:15触发 0 15 10 15 * ?
每月最后一天的上午10:15触发 0 15 10 L * ?
每月的第三个星期五上午10;15触发 0 15 10 ? * 6#3
5、Spring Tash @Scheduled
@Scheduled指定方法定时执行
@Scheduled写在方法上方,指定该方法定时执行,常用参数如下:
- cron :cron制定方法执行的时间规则
- fixedDelay :任务立即执行,之后每隔多久就执行一次,单位是毫秒,上次任务结束后计算下次执行的时间
//立即执行,任务结束后每5秒执行一次
@Scheduled(fixedDelay = 5000)
public void task2() throws InterruptedException {
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Thread.sleep(1000);
System.out.println(format.format(new Date()));
}
- fixedRate:任务立即执行,之后每隔多久就执行一次,单位毫秒,上次任务开始后开始计时
//立即执行,任务开始后每5秒执行一次
@Scheduled(fixedRate = 5000)
public void task3() throws InterruptedException {
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Thread.sleep(1000);
System.out.println(format.format(new Date()));
}
- initialDelay:项目启动后不马上执行定时器,根据initialDelay 延时执行
//项目启动3s后,之后每5s执行一次
@Scheduled(fixedRate = 5000,initialDelay = 3000)
public void task4() throws InterruptedException {
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Thread.sleep(1000);
System.out.println(format.format(new Date()));
}
6、Spring Task 多线程任务
Spring Task定时器默认是单线程的,如果项目中使用多个定时器,使用一个线程会造成效率低下如:
@Scheduled(cron = "* * * * * *")
public void task5() throws InterruptedException {
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Thread.sleep(5000);
System.out.println(format.format(new Date())+Thread.currentThread().getId()+"线程任务1");
}
@Scheduled(cron = "* * * * * *")
public void task6() throws InterruptedException {
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Thread.sleep(5000);
System.out.println(format.format(new Date())+Thread.currentThread().getId()+"线程任务2");
}
解决这个问题我们可以创建一个线程池。
@Configuration
public class SchedulingConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
//创建线程池
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
}
}
标签:触发,搞定,Task,15,14,format,Spring,执行,10 From: https://www.cnblogs.com/hellotqq/p/17033841.html欢迎转载,转载请注明原文出处
个人公众号 :hellotqq,欢迎关注交流与您共同成长!