SpringBoot中使用task實現定時任務


定時任務實現的幾種方式:

  • Timer:這是java自帶的java.util.Timer類,這個類允許你調度一個java.util.TimerTask任務。使用這種方式可以讓你的程序按照某一個頻度執行,但不能在指定時間運行。一般用的較少。
  • ScheduledExecutorService:也jdk自帶的一個類;是基於線程池設計的定時任務類,每個調度任務都會分配到線程池中的一個線程去執行,也就是說,任務是並發執行,互不影響。
  • Spring Task:Spring3.0以后自帶的task,可以將它看成一個輕量級的Quartz,而且使用起來比Quartz簡單許多。
  • Quartz:這是一個功能比較強大的的調度器,可以讓你的程序在指定時間執行,也可以按照某一個頻度執行,配置起來稍顯復雜。(如果SpringBoot版本是2.0.0以后的,則在spring-boot-starter中已經包含了quart的依賴,則可以直接使用spring-boot-starter-quartz依賴)

項目中需要實現一個每天凌晨定期清理緩存的功能,感覺上Quartz太重了,就選擇了Spring Task,簡單易實現

使用時,首先在啟動類中加上@EnableScheduling注解來開啟定時任務

@SpringBootApplication
@EnableScheduling             //開啟計划任務支持
public class SpringtaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringtaskApplication.class, args);
    }
}

然后就可以實現自己的功能了

@Scheduled是定時任務的注解
@Scheduled有三種定時任務的執行方式,包括fixedDelay、fixedRate、corn表達式
fixedDelay:指定兩次任務執行的時間間隔(毫秒),此時間間隔指的是,前一次任務結束與下一個任務開始的間隔。如:@Scheduled(fixedDelay = 5*1000 ),表示第一個任務結束后,過5秒后,開始第二個任務。
fixedRate:指定兩次任務執行的時間間隔(毫秒),此時間間隔指的是,前一個任務開始與下一個任務開始的間隔。如:
@Scheduled(fixedRate= 5*1000 ),表示第一個任務開始后(第一個任務執行時間小於5秒),第一個任務開始后的第6秒,開始第二個任務。如果第一個任務執行時間大於5秒,第一個任務結束后,直接開始第二個任務。
cron:通過表達式來配置任務執行時間

如果任務執行長度超過周期,且為單線程,結果如下圖:(圖來源:https://blog.csdn.net/applebomb/article/details/52400154)

 

cron表達式詳解

一個cron表達式有至少6個(也可能7個)有空格分隔的時間元素。按順序依次為:

  • 秒(0~59)
  • 分鍾(0~59)
  • 小時(0~23)
  • 天(0~31)
  • 月(0~11)
  • 星期(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)
  • 年份(1970-2099)(可選)
“/”:表示為“每”,如“0/10”表示每隔10分鍾執行一次,“0”表示為從“0”分開始, “3/20”表示表示每隔20分鍾執行一次
“?”:只用於月與周,表示不指定值
“*” 代表整個時間段。
“L”:只用於月與周,5L用在月表示為每月的最后第五天天;1L用在周表示每周的最后一天;
“W”::表示有效工作日(周一到周五),只能出現在day-of-month,系統將在離指定日期的最近的有效工作日觸發事件。例如:在 DayofMonth使用5W,如果5日是星期六,則將在最近的工作日:星期五,即4日觸發。如果5日是星期天,則在6日(周一)觸發;如果5日在星期一到星期五中的一天,則就在5日觸發。另外一點,W的最近尋找不會跨過月份 
“#”:用於確定每個月第幾個星期幾,只能出現在DayofMonth域。例如在4#2,表示某月的第二個星期三。
“C”:代表“Calendar”的意思。它的意思是計划所關聯的日期,如果日期沒有被關聯,則相當於日歷中所有日期。
注意:每個元素可以是一個值(如6),一個連續區間(9-12),一個間隔時間(8-18/4)(/表示每隔4小時),一個列表(1,3,5),通配符。由於"月份中的日期"和"星期中的日期"這兩個元素互斥的,必須要對其中一個設置‘?’

一些網上找的實例

0 0 10,14,16 * * ? 每天上午10點,下午2點,4點
0 0/30 9-17 * * ?   朝九晚五工作時間內每半小時
0 0 12 ? * WED 表示每個星期三中午12點 
"0 0 12 * * ?" 每天中午12點 
"0 15 10 ? * *" 每天上午10:15 
"0 15 10 * * ?" 每天上午10:15 
"0 15 10 * * ? *" 每天上午10:15 
"0 15 10 * * ? 2005" 2005年的每天上午10:15 
"0 * 14 * * ?" 在每天下午2點到下午2:59期間的每1分鍾 
"0 0/5 14 * * ?" 在每天下午2點到下午2:55期間的每5分鍾 
"0 0/5 14,18 * * ?" 在每天下午2點到2:55期間和下午6點到6:55期間的每5分鍾 
"0 0-5 14 * * ?" 在每天下午2點到下午2:05期間的每1分鍾 
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44 
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15 
"0 15 10 15 * ?" 每月15日上午10:15 
"0 15 10 L * ?" 每月最后一日的上午10:15 
"0 15 10 ? * 6L" 每月的最后一個星期五上午10:15 
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一個星期五上午10:15 
"0 15 10 ? * 6#3" 每月的第三個星期五上午10:15 

完成我的任務,每天0點定時清理緩存

@Component
public class TestSchedule {
    @Scheduled(cron = "0 0 0 * * ?")  //每天零點執行
    public void printDate(){
        System.out.println(new Date().toString());
xxxxxxx } }

當定時任務很多的時候,為了提高任務執行效率,可以采用並行方式執行定時任務,任務之間互不影響, 只要實現SchedulingConfigurer接口就可以。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM