1. 程式人生 > >作業排程框架 Quartz 學習筆記(三) -- Cron表示式

作業排程框架 Quartz 學習筆記(三) -- Cron表示式

  前面兩篇說的是簡單的觸發器(SimpleTrigger) , SimpleTrigger 只能處理簡單的事件出發,如果想靈活的進行任務的觸發,就要請出

CronTrigger 這個重要人物了.

    CronTrigger也是Quartz最重要的特色之一,通過Quartz特有的Cron表示式來確定某類時間,能完成類似"2011年11月11號(神棍節,已經過去了),每個星期三XXX"之類的複雜定時任務。 

程式碼還是老套路 , 兩個類 : SimpleJob.java  和 CronTriggerExample.java

建議先跑程式碼 ,看結果 ,然後再 看程式碼

SimpleJob.java

  1. import
     java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import org.quartz.Job;  
  4. import org.quartz.JobExecutionContext;  
  5. import org.quartz.JobExecutionException;  
  6. publicclass SimpleJob implements Job {  
  7.     @Override
  8.     publicvoid execute(JobExecutionContext context)  
  9.             throws JobExecutionException {  
  10.         // job 的名字
  11.         String jobName = context.getJobDetail().getKey().getName();  
  12.         // 任務執行的時間
  13.         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy 年 MM 月 dd 日  HH 時 mm 分 ss 秒");  
  14.         String jobRunTime = dateFormat.format(Calendar.getInstance().getTime());  
  15.         // 輸出任務執行情況
  16.         System.out.println("任務 : "
     + jobName + " 在  " +jobRunTime + " 執行了 ");  
  17.     }  
  18. }  

CronTriggerExample.java

  1. importstatic org.quartz.CronScheduleBuilder.cronSchedule;  
  2. importstatic org.quartz.JobBuilder.newJob;  
  3. importstatic org.quartz.TriggerBuilder.newTrigger;  
  4. import java.text.SimpleDateFormat;  
  5. import java.util.Date;  
  6. import org.quartz.CronTrigger;  
  7. import org.quartz.JobDetail;  
  8. import org.quartz.Scheduler;  
  9. import org.quartz.SchedulerFactory;  
  10. import org.quartz.SchedulerMetaData;  
  11. import org.quartz.impl.StdSchedulerFactory;  
  12. /** 
  13.  * Cron Triggers 的使用 
  14.  */
  15. publicclass CronTriggerExample {  
  16.     publicstaticvoid main(String[] args) throws Exception {  
  17.         CronTriggerExample example = new CronTriggerExample();  
  18.         example.run();  
  19.     }  
  20.     publicvoid run() throws Exception {  
  21.         // 日期格式化
  22.         SimpleDateFormat dateFormat = new SimpleDateFormat(  
  23.                 "yyyy 年 MM 月 dd 日  HH 時 mm 分 ss 秒");  
  24.         SchedulerFactory sf = new StdSchedulerFactory();  
  25.         Scheduler sched = sf.getScheduler();  
  26.         System.out.println("--------------- 初始化 -------------------");  
  27.         // job1 每20s執行一次
  28.         JobDetail job = newJob(SimpleJob.class).withIdentity("job1""group1")  
  29.                 .build();  
  30.         CronTrigger trigger = newTrigger().withIdentity("trigger1""group1")  
  31.                 .withSchedule(cronSchedule("0/20 * * * * ?")).build();  
  32.         Date ft = sched.scheduleJob(job, trigger);  
  33.         System.out.println(job.getKey().getName() + " 將在: "
  34.                 + dateFormat.format(ft) + " 執行 . 並且基於Cron表示式 : "
  35.                 + trigger.getCronExpression() + "  (含義:每20s執行一次)");  
  36.         // job2 偶數分鐘的第15秒執行
  37.         job = newJob(SimpleJob.class).withIdentity("job2""group1").build();  
  38.         trigger = newTrigger().withIdentity("trigger2""group1")  
  39.                 .withSchedule(cronSchedule("15 0/2 * * * ?")).build();  
  40.         ft = sched.scheduleJob(job, trigger);  
  41.         System.out.println(job.getKey().getName() + " 將在: "
  42.                 + dateFormat.format(ft) + " 執行 . 並且基於Cron表示式 : "
  43.                 + trigger.getCronExpression() + "  (含義:偶數分鐘的第15秒執行)");  
  44.         // job3 從8時到17時 ,每個 偶數分鐘執行一次
  45.         job = newJob(SimpleJob.class).withIdentity("job3""group1").build();  
  46.         trigger = newTrigger().withIdentity("trigger3""group1")  
  47.                 .withSchedule(cronSchedule("0 0/2 8-17 * * ?")).build();  
  48.         ft = sched.scheduleJob(job, trigger);  
  49.         System.out.println(job.getKey().getName() + " 將在: "
  50.                 + dateFormat.format(ft) + " 執行 . 並且基於Cron表示式 : "
  51.                 + trigger.getCronExpression() + "  (含義:從8時到17時 ,每個 偶數分鐘執行一次)");  
  52.         // job4 從17時到23時,每3分鐘執行一次
  53.         job = newJob(SimpleJob.class).withIdentity("job4""group1").build();  
  54.         trigger = newTrigger().withIdentity("trigger4""group1")  
  55.                 .withSchedule(cronSchedule("0 0/3 17-23 * * ?")).build();  
  56.         ft = sched.scheduleJob(job, trigger);  
  57.         System.out.println(job.getKey().getName() + " 將在: "
  58.                 + dateFormat.format(ft) + " 執行 . 並且基於Cron表示式 : "
  59.                 + trigger.getCronExpression() + "  (含義: 從17時到23時,每3分鐘執行一次)");  
  60.         // job5 每個月的1號和15號的上午10點 執行
  61.         job = newJob(SimpleJob.class).withIdentity("job5""group1").build();  
  62.         trigger = newTrigger().withIdentity("trigger5""group1")  
  63.                 .withSchedule(cronSchedule("0 0 10am 1,15 * ?")).build();  
  64.         ft = sched.scheduleJob(job, trigger);  
  65.         System.out.println(job.getKey().getName() + " 將在: "
  66.                 + dateFormat.format(ft) + " 執行 . 並且基於Cron表示式 : "
  67.                 + trigger.getCronExpression() + "  (含義:每個月的1號和15號的上午10點 執行)");  
  68.         // job6 週一至週五,每30秒執行一次
  69.         job = newJob(SimpleJob.class).withIdentity("job6""group1").build();  
  70.         trigger = newTrigger().withIdentity("trigger6""group1")  
  71.                 .withSchedule(cronSchedule("0,30 * * ? * MON-FRI")).build();  
  72.         ft = sched.scheduleJob(job, trigger);  
  73.         System.out.println(job.getKey().getName() + " 將在: "
  74.                 + dateFormat.format(ft) + " 執行 . 並且基於Cron表示式 : "
  75.                 + trigger.getCronExpression() + "  (含義:週一至週五,每30秒執行一次 )");  
  76.         // job7 週六,週日 每30秒執行
  77.         job = newJob(SimpleJob.class).withIdentity("job7""group1").build();  
  78.         trigger = newTrigger().withIdentity("trigger7""group1")  
  79.                 .withSchedule(cronSchedule("0,30 * * ? * SAT,SUN")).build();  
  80.         ft = sched.scheduleJob(job, trigger);  
  81.         System.out.println(job.getKey().getName() + " 將在: "
  82.                 + dateFormat.format(ft) + " 執行 . 並且基於Cron表示式 : "
  83.                 + trigger.getCronExpression() + "  (含義:週六,週日  每30秒執行 )");  
  84.         sched.start();  
  85.         System.out.println("------- 開始排程 (呼叫.start()方法) ----------------");  
  86.         System.out.println("------- 等待5分鐘,給任務的排程留出時間  ... ------------");  
  87.         try {  
  88.             Thread.sleep(300L * 1000L);  
  89.         } catch (Exception e) {  
  90.         }  
  91.         sched.shutdown(true);  
  92.         System.out.println("------- 排程已關閉 ---------------------");  
  93.         // 顯示一下 已經執行的任務資訊
  94.         SchedulerMetaData metaData = sched.getMetaData();  
  95.         System.out.println("~~~~~~~~~~  執行了 "
  96.                 + metaData.getNumberOfJobsExecuted() + " 個 jobs.");  
  97.     }  
  98. }  


 你也許發現什麼是關鍵了?  

yes你是對的.就是這些東西 

0 0/2 8-17 * * ?  

0 0 10am 1,15 * ?

0,30 * * ? * MON-FRI

由它們可以 靈活的組織出 你想要執行任務的時間.下面讓我們來看看這東西的具體含義

在這之前,我們先看一下幾個例子吧:

  1. --------------------------------------
  2.     0 0 12 * * ?            每天12點觸發
  3.     0 15 10 ? * *           每天10點15分觸發
  4.     0 15 10 * * ?           每天10點15分觸發
  5.     0 15 10 * * ? *         每天10點15分觸發
  6.     0 15 10 * * ? 2005      2005年每天10點15分觸發
  7.     0 * 14 * * ?            每天下午的 2點到2點59分每分觸發
  8.     0 0/5 14 * * ?          每天下午的 2點到2點59分(整點開始,每隔5分觸發)
  9.     0 0/5 14,18 * * ?       每天下午的 2點到2點59分(整點開始,每隔5分觸發) 每天下午的 18點到18點59分(整點開始,每隔5分觸發)
  10.     0 0-5 14 * * ?          每天下午的 2點到2點05分每分觸發
  11.     0 10,44 14 ? 3 WED      3月分每週三下午的 2點10分和2點44分觸發
  12.     0 15 10 ? * MON-FRI     從週一到週五每天上午的10點15分觸發
  13.     0 15 10 15 * ?          每月15號上午10點15分觸發
  14.     0 15 10 L * ?           每月最後一天的10點15分觸發
  15.     0 15 10 ? * 6L          每月最後一週的星期五的10點15分觸發
  16.     0 15 10 ? * 6L 2002-2005    從2002年到2005年每月最後一週的星期五的10點15分觸發
  17.     0 15 10 ? * 6#3         每月的第三週的星期五開始觸發
  18.     0 0 12 1/5 * ?          每月的第一個中午開始每隔5天觸發一次
  19.     0 11 11 11 11 ?         每年的11月11號 11點11分觸發(光棍節)
  20. --------------------------------------

怎麼樣? 有沒有發現規律,還用往下看嗎? 你說了蒜 0.0~!

CronTrigger配置格式:

格式: [秒] [分] [小時] [日] [月] [周] [年]

序號說明是否必填允許填寫的值允許的萬用字元
10-59   , - * /
20-59  , - * /
3小時0-23  , - * /
41-31  , - * ? / L W
51-12 or JAN-DEC  , - * /
61-7 or SUN-SAT  , - * ? / L #
7empty 或 1970-2099, - * /


萬用字元說明:
*表示所有值. 例如:在分的欄位上設定 "*",表示每一分鐘都會觸發。
? 表示不指定值。使用的場景為不需要關心當前設定這個欄位的值。例如:要在每月的10號觸發一個操作,但不關心是周幾,所以需要周位置的那個欄位設定為"?" 具體設定為 0 0 0 10* ?
- 表示區間。例如 在小時上設定 "10-12",表示 10,11,12點都會觸發。
, 表示指定多個值,例如在周欄位上設定 "MON,WED,FRI" 表示週一,週三和週五觸發
/用於遞增觸發。如在秒上面設定"5/15" 表示從5秒開始,每增15秒觸發(5,20,35,50)。 在月欄位上設定'1/3'所示每月1號開始,每隔三天觸發一次。
L 表示最後的意思。在日欄位設定上,表示當月的最後一天(依據當前月份,如果是二月還會依據是否是潤年[leap]), 在周欄位上表示星期六,相當於"7"或"SAT"。如果在"L"前加上數字,則表示該資料的最後一個。例如在周欄位上設定"6L"這樣的格式,則表示“本月最後一個星期五"
W 表