今天和大家分享下Spring Task這個知識點,主要通過下面6個點來展開描述,希望能夠幫助到大家。
1、什麼是定時任務
2、入門案例
3、Corn表示式
4、Corn實戰案例
5、@Scheduled
6、多執行緒任務
定時任務是系統在特定時間執行一段程式碼。
定時任務的實現主要有以下幾種方式:
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()));
}
Spring Task 依靠Corn表示式設定定時規則,Corn表示式是一個字串,分為6或7個域。每個域代表一個含義,以空格隔開,有如下兩種語法格式:
1、秒 分 時 每月第幾天 月份 周幾 年份
2、秒 分 時 每月第幾天 月份 周幾
Seconds(秒)域可以出現,- * /
和0-59
的整數
*:表示匹配該域的任意值,在Seconds域中使用 * 表示每秒鐘都會出發
,:表示列出列舉值,在Seconds域中使用5,20表示在5秒和20秒各觸發一次
-:表示範圍,在secondes域使用5-20,表示從5秒到20秒每秒觸發一次
/:表示起始時間開始觸發,然後每隔固定時間觸發一次,在secondes域中使用5/20,表示第5秒觸發一次,25秒、45秒各觸發一次。
以上四個字元在minutes和Hours域都可以出現。分鐘整數為0-59,小時整數為0-23
DayofMonty(日期):域中可以出現,- * / ? L W C 八個字元,以及1-31的整數。
5c
,則在執行當天的5日後執行,且每月的那天都會執行。比如執行日是10號,則每月的15號都會觸發。Month(月份):域中可出現,- * /
四個字元,以及1-12的整數或JAN-DEC的單詞縮寫
DayofWeek(星期):可出現,- * / ? L # C
八個字元,以及1-7的整數或SUN-SAT單詞的縮寫,1代表星期天,7代表週六
5L
,表示在一個月的最後一個週四觸發5#3
表示一個月第三週的星期四0 0 0 21 * ?
Year(年份):,- * /
四個字元,以及 1970~2099的整肅,該域可以省略,表示每年都會觸發。
每間隔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
@Scheduled指定方法定時執行
@Scheduled寫在方法上方,指定該方法定時執行,常用引數如下:
//立即執行,任務結束後每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()));
}
//立即執行,任務開始後每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()));
}
//專案啟動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()));
}
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));
}
}
歡迎轉載,轉載請註明原文出處
個人公眾號 :hellotqq,歡迎關注交流與您共同成長!