任務調度SpringTask

1、任務調度的概念

  在企業級應用中,會常常指定一些計劃任務,即在某個時間點作某件事情,核心是以時間爲關注點,即在一個特定的時間點,系統執行特定的一個操做,常見的任務調度框架有Quartz和SpringTask等。其中SpringTask是spring在spring3後自帶支持的定時任務。下面的demo講述的就是SpringTask。spring

2、入門demo

  2.1 建立SpringBoot工程 -- pom.xml上加上SpringBoot的基本依賴

  • 在啓動類上加上註解:@EnableScheduling
  • 在須要執行定時任務的方法上加上@Scheduled(cron = "* * * * * ?")表示執行定時任務的週期
1 @EnableScheduling
2 @SpringBootApplication
3 public class SpringTaskApplication {
4 
5     public static void main(String[] args) {
6         SpringApplication.run(SpringTaskApplication.class, args);
7     }
8 }
 1 @Component
 2 public class SpringTaskDemo {
 3     /**
 4      * 定時刷新
 5      */
 6     /**
 7      * @Scheduled(fixedRate = 5000) //上次執行開始時間後5秒執行
 8      * @Scheduled(fixedDelay = 5000)  //上次執行完畢後5秒執行
 9      * @Scheduled(initialDelay=3000, fixedRate=5000) //第一次延遲3秒,之後每隔5秒執行一次
10      */
11     @Scheduled(cron = "* * * * * ?")
12     public void task01() throws InterruptedException {
13         System.out.println("開始執行了任務調度task01" + new Date());
14         Thread.sleep(5000);
15         System.out.println("結束執行了任務調度task01" + new Date());
16     }
17 }

  注:上面的任務執行打印開始結束,以及中間的線程休眠時間,主要是爲了展現串行並行過程的效果。多線程

  • 執行引導類的main方法,控制檯打印消息

  2.2 Cron表達式

  格式:Cron表達式是一個字符串,字符串以5或6個空格隔開,分爲6或7個域,每個域表明一個含義,Cron有以下兩種語法格式:框架

  (1)Seconds Minutes Hours DayofMonth Month DayofWeek Yearide

  (2)Seconds Minutes Hours DayofMonth Month DayofWeek測試

  每個域可出現的字符以下:spa

  Seconds:可出現", - * /"四個字符,有效範圍爲0-59的整數線程

  Minutes:可出現", - * /"四個字符,有小範圍爲0-59的整數3d

  Hours:可出現", - * /"四個字符,有效範圍爲0-23的整數code

  DayofMonth:可出現", - * / ? L W C"八個字符,有效範圍爲1-31的整數xml

  Month:可出現", - * /"四個字符,有效範圍爲1-12的整數或JAN-DEC(月份的簡稱)

  DayofWeek:可出現", - * / ? L C #"八個字符,有效範圍爲1-7的整數或SUN-SAT(星期的簡稱)兩個範圍,1表示星期天,2表示星期一,依次類推

  YEAR:可出現", - * /"四個字符,有效範圍是1970-2099年

  (1),:表示列出枚舉值,例如,在Minutes域使用"5,20"。則意味着在5和20分每分鐘觸發一次;

  (2)-:表示範圍,例如在Minutes域使用"5-20",表示從5分到20分每分鐘觸發一次;

  (3)*:表示匹配該域的任意值,假如在Minutes域中使用"*「,表示每分鐘都會觸發事件;

  (4)/:表示起始時間開始觸發,而後每隔固定時間觸發一下,例如在Minutes域中使用5/20,則意味着第5分鐘觸發一次,而後第25分,45分觸發一次;

-----------------------------如下符號只能出如今DayofMonth和DayofWeek兩個域-----------------------------

  (5)?:它也匹配任意值,但其實不會。由於DayofMonth和DayofWeek會相互影響。例如想在每個月的20日觸發調度,無論是20日究竟是星期幾,兩個位置當一個位置取一個特定含義的值後另一個位置只能用?佔位,例如:12 12 15 20 * ?;

  (6)L:表示最後,例如在DayofWeek域使用5L,意味着在最後的一個星期四觸發;

---------------------------------------------------------分割線---------------------------------------------------------

  (7)W:表示有效工做日(週一到週五),只能出如今DayofMonth域中,系統將在離指定日期的最近的有效工做日觸發事件。例如:在DayofMonth使用5W,若是5日是星期六,則在最近的工做日:星期五,即4日觸發。若是5日是星期天,則在6日(週一)觸發;若是5日在星期一到週五中的一天,,則就在5日觸發。另一點,W的最近尋找不會跨過月份;

  (8)#:用於肯定第幾個月的第幾個星期幾,只能出如今DayofWeek域,例如:4#2,表示某月的第二個星期三。

   2.3 串行化任務

  參看task01定義task02方法,此時任務公用兩個任務方法

 1     /**
 2      * 上次執行開始時間後5秒執行
 3      * @throws InterruptedException
 4      */
 5     @Scheduled(fixedRate = 5000)
 6     public void task02() throws InterruptedException {
 7         System.out.println("開始執行了任務調度task02" + new Date());
 8         Thread.sleep(5000);
 9         System.out.println("結束執行了任務調度task02" + new  Date());
10     }

  測試發現,兩個方法由一個線程串行執行,task01方法執行完成task02再執行

  2.4 並行任務

  咱們發現有時候在項目中咱們須要多個不一樣的任務並行的執行,下面執行配置線程池實現多線程調度任務。取消SpringBoot啓動類上的@EnableScheduling註解

 1 @Configuration
 2 @EnableScheduling
 3 public class SpringTaskParallelDemo implements SchedulingConfigurer,AsyncConfigurer{
 4     @Bean
 5     public ThreadPoolTaskScheduler taskScheduler(){
 6         ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
 7         // 初始化線程池
 8         scheduler.initialize();
 9         // 線程池容量
10         int corePoolSize = 5;
11         scheduler.setPoolSize(corePoolSize);
12         return scheduler;
13     }
14 
15     @Override
16     public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
17         scheduledTaskRegistrar.setTaskScheduler(taskScheduler());
18     }
19 
20     @Override
21     public Executor getAsyncExecutor() {
22         return taskScheduler();
23     }
24 
25     @Override
26     public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
27         return null;
28     }
29 }

  測試,發現兩個任務由不一樣的線程並行執行,互不影響。

相關文章
相關標籤/搜索