1. 程式人生 > >作業排程框架 Quartz 學習筆記(四) -- 接收引數和維護狀態

作業排程框架 Quartz 學習筆記(四) -- 接收引數和維護狀態

<<Quartz中Job的引數傳遞和狀態儲存>>

如果你想在 某個job執行的時候傳入引數,引數在job執行過程中對引數有所修改,並且在job執行完畢後把引數返回
那麼你需要學習一下現在的這個例子了,因為它正是你所想要的 ......

我的建議是先把程式碼執行起來看結果,然後再去看程式碼.

還是老套路,兩個類 一個job類:ColorJob.java   一個排程類: JobStateExample.java

程式碼 :

ColorJob.java

/**
 * <p> 這只是一個簡單的工作,接收引數和維護狀態  </p>
 */
//小心,這裡的註釋很重要
@PersistJobDataAfterExecution @DisallowConcurrentExecution public class ColorJob implements Job { // 靜態變數 public static final String FAVORITE_COLOR = "favorite color"; public static final String EXECUTION_COUNT = "count"; // Quartz 將每次將會重新例項化物件 ,非靜態的成員變數不能用來保持狀態 private int _counter = 1; @Override public void execute(JobExecutionContext context) throws JobExecutionException { // job 的名字 String jobName = context.getJobDetail().getKey().getName(); // 任務執行的時間 SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy 年 MM 月 dd 日 HH 時 mm 分 ss 秒"); String jobRunTime = dateFormat.format(Calendar.getInstance().getTime()); // 獲取 JobDataMap , 並從中取出引數 JobDataMap data = context.getJobDetail().getJobDataMap(); String favoriteColor = data.getString(FAVORITE_COLOR); int count = data.getInt(EXECUTION_COUNT); System.out .println("ColorJob: " + jobName + " 在 " + jobRunTime + " 執行了 ... \n" + " 喜歡的顏色是: " + favoriteColor + "\n" + " 執行次數統計(from job jobDataMap): " + count + "\n" + " 執行次數統計( from job 類的成員變 量 ): " + _counter+ " \n "); // 每次+1 並放回Map 中 count++; data.put(EXECUTION_COUNT, count); // 成員變數的增加沒有意義,每次例項化物件的時候會 同時初始化該變數 _counter++; } }

JobStateExample.java

import static org.quartz.DateBuilder.nextGivenSecondDate;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;

public class JobStateExample {

	public static void main(String[] args) throws Exception {
		JobStateExample example = new JobStateExample();
		example.run();
	}

	public void run() throws Exception {

		// 日期格式化
		SimpleDateFormat dateFormat = new SimpleDateFormat(
				"yyyy 年 MM 月 dd 日  HH 時 mm 分 ss 秒");
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler sched = sf.getScheduler();
		System.out.println("--------------- 初始化 -------------------");

		// 下一個10秒,不懂的去查API
		Date startTime = nextGivenSecondDate(null, 10);

		// job1 第10秒執行一次,共執行5次
		JobDetail job1 = newJob(ColorJob.class).withIdentity("job1", "group1")
				.build();

		SimpleTrigger trigger1 = newTrigger()
				.withIdentity("trigger1", "group1")
				.startAt(startTime)
				.withSchedule(
						simpleSchedule().withIntervalInSeconds(10)
								.withRepeatCount(4)).build();

		// 初始化傳入的引數
		job1.getJobDataMap().put(ColorJob.FAVORITE_COLOR, "######  綠   #####");
		job1.getJobDataMap().put(ColorJob.EXECUTION_COUNT, 1);

		Date scheduleTime1 = sched.scheduleJob(job1, trigger1);
		System.out.println(job1.getKey().getName() + " 將在 : "
				+ dateFormat.format(scheduleTime1) + " 執行, 並重復 : "
				+ trigger1.getRepeatCount() + " 次, 每次間隔   "
				+ trigger1.getRepeatInterval() / 1000 + " 秒");

		// job2 每10秒執行一次,共執行5次
		JobDetail job2 = newJob(ColorJob.class).withIdentity("job2", "group1")
				.build();

		SimpleTrigger trigger2 = newTrigger()
				.withIdentity("trigger2", "group1")
				.startAt(startTime)
				.withSchedule(
						simpleSchedule().withIntervalInSeconds(10)
								.withRepeatCount(4)).build();

		// 初始化傳入的引數
		job2.getJobDataMap().put(ColorJob.FAVORITE_COLOR, "######  紅   #####");
		job2.getJobDataMap().put(ColorJob.EXECUTION_COUNT, 1);

		Date scheduleTime2 = sched.scheduleJob(job2, trigger2);
		System.out.println(job2.getKey().getName() + " 將在 : "
				+ dateFormat.format(scheduleTime2) + " 執行, 並重復 : "
				+ trigger2.getRepeatCount() + " 次, 每次間隔   "
				+ trigger2.getRepeatInterval() / 1000 + " 秒");

		System.out.println("------- 開始排程 (呼叫.start()方法) ----------------");
		sched.start();

		System.out.println("------- 等待60秒 ... -------------");
		try {
			Thread.sleep(60L * 1000L);
		} catch (Exception e) {
		}

		sched.shutdown(true);
		System.out.println("------- 排程已關閉 ---------------------");

		// 顯示一下 已經執行的任務資訊
		SchedulerMetaData metaData = sched.getMetaData();
		System.out.println("~~~~~~~~~~  執行了 "
				+ metaData.getNumberOfJobsExecuted() + " 個 jobs.");

		/*
		如果你想在 某個job執行的時候傳入引數,引數在job執行過程中對引數有所修改,並且在job執行完畢後把引數返回
		那麼你需要學習一下現在的這個例子了,因為它正是你所想要的
		 */
	}

}


執行結果 :

--------------- 初始化 -------------------
job1 將在 : 2013 年 03 月 07 日  14 時 02 分 00 秒 執行, 並重復 : 4 次, 每次間隔   10 秒
job2 將在 : 2013 年 03 月 07 日  14 時 02 分 00 秒 執行, 並重復 : 4 次, 每次間隔   10 秒
------- 開始排程 (呼叫.start()方法) ----------------
------- 等待60秒 ... -------------
ColorJob: job2 在 2013 年 03 月 07 日  14 時 02 分 00 秒 執行了 ...  
      喜歡的顏色是:  ######  紅   #####
      執行次數統計(from job jobDataMap): 1
      執行次數統計( from job 類的成員變 量 ): 1 
 
ColorJob: job1 在 2013 年 03 月 07 日  14 時 02 分 00 秒 執行了 ...  
      喜歡的顏色是:  ######  綠   #####
      執行次數統計(from job jobDataMap): 1
      執行次數統計( from job 類的成員變 量 ): 1 
 
ColorJob: job1 在 2013 年 03 月 07 日  14 時 02 分 10 秒 執行了 ...  
      喜歡的顏色是:  ######  綠   #####
      執行次數統計(from job jobDataMap): 2
      執行次數統計( from job 類的成員變 量 ): 1 
 
ColorJob: job2 在 2013 年 03 月 07 日  14 時 02 分 10 秒 執行了 ...  
      喜歡的顏色是:  ######  紅   #####
      執行次數統計(from job jobDataMap): 2
      執行次數統計( from job 類的成員變 量 ): 1 
 
ColorJob: job1 在 2013 年 03 月 07 日  14 時 02 分 20 秒 執行了 ...  
      喜歡的顏色是:  ######  綠   #####
      執行次數統計(from job jobDataMap): 3
      執行次數統計( from job 類的成員變 量 ): 1 
 
ColorJob: job2 在 2013 年 03 月 07 日  14 時 02 分 20 秒 執行了 ...  
      喜歡的顏色是:  ######  紅   #####
      執行次數統計(from job jobDataMap): 3
      執行次數統計( from job 類的成員變 量 ): 1 
 
ColorJob: job1 在 2013 年 03 月 07 日  14 時 02 分 30 秒 執行了 ...  
      喜歡的顏色是:  ######  綠   #####
      執行次數統計(from job jobDataMap): 4
      執行次數統計( from job 類的成員變 量 ): 1 
 
ColorJob: job2 在 2013 年 03 月 07 日  14 時 02 分 30 秒 執行了 ...  
      喜歡的顏色是:  ######  紅   #####
      執行次數統計(from job jobDataMap): 4
      執行次數統計( from job 類的成員變 量 ): 1 
 
ColorJob: job1 在 2013 年 03 月 07 日  14 時 02 分 40 秒 執行了 ...  
      喜歡的顏色是:  ######  綠   #####
      執行次數統計(from job jobDataMap): 5
      執行次數統計( from job 類的成員變 量 ): 1 
 
ColorJob: job2 在 2013 年 03 月 07 日  14 時 02 分 40 秒 執行了 ...  
      喜歡的顏色是:  ######  紅   #####
      執行次數統計(from job jobDataMap): 5
      執行次數統計( from job 類的成員變 量 ): 1 
 
------- 排程已關閉 ---------------------
~~~~~~~~~~  執行了 10 個 jobs.

說明 :

JobStateExample.java 類中 的 47/48 、68/69 行程式碼 向JobDataMap 中放入值

ColorJob.java 類的 38-49 行對其進行了操作,然後又將引數放回到 JobDataMap中 

 對於單個任務來說:

  • 普通私有成員變數的操作不會影響到下次執行結果,_counter每次執行都是初始值1
  • JobDataMap容器中儲存的favorite color 、count  可以保持狀態和引數傳遞

引數傳遞和狀態處理方式:

 1.引數傳遞。使用job.getJobDataMap().put()方式向Job當中傳遞引數,JobDataMap類實際上最終繼承了實現Map介面的"DirtyFlagMap"類,而DirtyFlagMap內部又儲存了一個HashMap的引用,操作都是針對這個HashMap進行的。

2.JobDataMap的持久化 即PersistJobDataAfterExecution這個註解的使用。加上註解之後,每次執行完,JobDataMap都會被序列化,上次任務執行放入的值都會儲存下來。

關於ColorJob.java   17/18  行的註解:

@PersistJobDataAfterExecution   儲存在JobDataMap傳遞的引數

   
@DisallowConcurrentExecution   保證多個任務間不會同時執行.所以在多工執行時最好加上