今日学习心得:
在开发过程中避免不了一些周期性的定时任务,比如定时同步数据库,定时发送邮件,定时初始化数据等等。
如何使用Scheduler:
1:使用@EnableScheduling启用定时任务
2:使用@Scheduled编写相关定时任务
开启定时任务:
在程序中添加@EnableScheduling注解即可启用Spring的定时功能,这类似于Spring的XML中的task:*功能。
例子:
@SpringBootApplication
@EnableScheduling
public class ScheduleApplication{
public static void main(String[] args) throws Exception{
SpringApplication.run(App.class,args);
}
}
关于@Scheduled注解类的源码可以得知该注解支持如下几种方式使用定时任务
1.cron()
2.fixedDelay()
3:fixedDelayString()
4:fiexdRate()
5:fixedRateString()
6:initialDelay()
7:initialDelayString()
cron是定时任务中最常用的一种调度方式,主要在于它的功能强大,使用方便。支持cron语法,与linux中的crontab表达式类似,不过java中的cron支持到了秒:
表达式规则:{秒}{分}{时}{日}{月}{周}{年(可选)}
linux的crontab表达式为:{分}{时}{日}{月}{周}
项 取值范围 null 备注
秒 0-59 否 参考①
分 0-59 否 参考①
时 0-23 否 参考①
日 1-31 否 参考②
月 1-12或JAN-DEC 否 参考①
周 1-7或SUN-SAT 否 参考③
年 1970-2099 是 参考①
参考①:
“*” 每隔一单位触发;
“,” 在指定单位时间触发,比如"10,12"代表10单位时间,20单位时间时触发任务
“-” 在指定的范围内触发,比如"5-30"代表从5单位时间到30单位时间时每隔1单位时间触发一次
“/” 触发步进(step),“/”前面的值代表初始值( “ ” 等同“0”),后面的值代表偏移量,比如“0/25”或者“/25”代表从0单位时间开始,每隔25单位时间触发一次;“10-45/20”代表在[10-45]单位时间内每隔20单位时间触发一次。
参考②:(就是日的单位)
“*,- /” 这四个用法同①
“L” 如果{日}占位符如果是"L",即意味着当月的最后一天触发
“W” 意味着在本月内离当天最近的工作日触发。因此,“LW”则意味着本月的最后一个工作日触发,“W”强烈依赖{月}
“C” 根据日历触发,使用较少。
参考③:(就是周的单位)
“*,- /” 这四个用法同①
“?” 与{日}互斥,即意味着若明确指定{日}触发,则表示{周}无意义,以免引起冲突和混乱。
“L” 如果{周}占位符是“L”,即意味着星期的最后一天触发,即星期六触发,L = 7或者 L = SAT ,因此, “5L” 意味着一个月的最后一个星期四触发
“#” 用来指定具体的周数,“#” 前面代表星期, “#”后面代表本月第几周,比如“2#2”表示本月第二周的星期一,“5#3”表示本月第三周的星期四,因此,“5L”这种形式只不过是“#”的特殊形式而已
“C” 根据日常触发,由于使用较少,暂时不做解释。
在11月7号晚上22点的7分到8分之间每隔半分钟(30秒) 执行一次任务
@Scheduled(cron = “0/30 7-8 22 7 11 ?”)
public void doJobByCron() throws InterruptedException {
int index = integer.incrementAndGet();
System.out.println(String.format("[%s] %s doJobByCron start @ %s", index, Thread.currentThread(), LocalTime.now()));
// 这儿随机睡几秒,方便查看执行效果
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
System.out.println(String.format("[%s] %s doJobByCron end @ %s", index, Thread.currentThread(), LocalTime.now()));
}
(这里的代码没看懂)
在线生成:Cron:http://cron.qqe2.com
fixedDelay
上一次任务执行完成后,延时固定长度时间执行下一次任务
上次任务执行完的3s后再次执行
@Scheduled(fixedDelay = 3000)
public void doJobByFixedDealy() throw InterruptedException {
int index = integer.incrementAndGet();
System.out.println(String.format("[%s] %s doJobByFixedDelay start @ %s", index, Thread.currentThread(), LocalTime.now()));
// 这儿随机睡几秒,方便查看执行效果
TimeUnit.SECONDS.sleep(new Random().nextInt(10));
System.out.println(String.format("[%s] %s doJobByFixedDelay end @ %s", index, Thread.currentThread(), LocalTime.now()));
Time Unit.SECOND.sleep(new Random().nextInt(10));
System.out.println(String.format("[%s] %s doJobByFixedDelay end @ %s",index,Thread.currentThread(),LocalTime.now()));
fixedRate:
按照固定的速率执行任务,无论之前的任务是否执行完毕。