1. 程式人生 > >Java定時任務Quartz二

Java定時任務Quartz二

1.Trigger通用屬性

      Trigger的觸發器通用屬性:JobKey——job例項的標識,觸發器被觸發時,該指定的job例項會執行;StartTime——表示觸發器的時間表首次被觸發的時間,它的值的型別是Java.util.Date;EndTime——指定觸發器不再被觸發的時間,它的值的型別是Java.util.Date;Job示例程式碼如下:

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.Trigger;
public class HelloJob implements Job{
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		//列印當前執行時間
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("任務執行時間為:"+sf.format(startTime));
		Trigger currentTrigger = context.getTrigger();
		System.out.println("Start Time is:"+sf.format(currentTrigger.getStartTime()));
		System.out.println("End Time is:"+sf.format(currentTrigger.getEndTime()));
		JobKey jobKey = currentTrigger.getJobKey();
		System.out.println("JobKey info---"+"jobName:"+jobKey.getName()+"jobGroup:"+jobKey.getGroup());
	}
}

Trigger示例程式碼如下:

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
	public static void main(String[] args) throws SchedulerException {
		// 建立一個JobDetail例項與HelloJob類繫結
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
		//列印當前時間
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("列印當前時間:"+sf.format(startTime));
		//獲取當前時間3秒後的時間
		startTime.setTime(startTime.getTime()+3000);
		//獲取當前時間6秒後的時間
		Date endDate = new Date();
		endDate.setTime(endDate.getTime()+6000);
		// 建立一個Trigger例項,定義該Job立即執行,且每隔兩秒鐘執行一次直到永遠
		Trigger trigger = TriggerBuilder.newTrigger().
				withIdentity("mtTrigger", "group1").
				startAt(startTime).endAt(endDate).
				withSchedule(SimpleScheduleBuilder.simpleSchedule().
				withIntervalInSeconds(2).repeatForever()).build();
		//建立scheduler例項
		SchedulerFactory sFactory = new StdSchedulerFactory();
		Scheduler scheduler = sFactory.getScheduler();
		scheduler.start();
		scheduler.scheduleJob(jobDetail,trigger);
	}
}

2.淺談SimpleTrigger

      SimpleTrigger:在一個指定時間段內執行一次作業任務,或者是在指定的時間間隔內多次執行作業任務。建立定時任務:距離當前時間4秒之後執行且僅執行一次,程式碼如下:

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloJob implements Job{
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		//列印當前執行時間
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("任務執行時間為:"+sf.format(startTime));
		System.out.println("Hello World!");
	}
}
package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
	public static void main(String[] args) throws SchedulerException {
		// 建立一個JobDetail例項與HelloJob類繫結
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
		//列印當前時間
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("列印當前時間:"+sf.format(startTime));
		//獲取距離當前時間4秒之後的時間
		startTime.setTime(startTime.getTime()+4000L);
		// 建立一個Trigger例項,距離當前時間4秒鐘後執行且僅執行一次任務
		SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger().
				withIdentity("mtTrigger", "group1").startAt(startTime).build();
		//建立scheduler例項
		SchedulerFactory sFactory = new StdSchedulerFactory();
		Scheduler scheduler = sFactory.getScheduler();
		scheduler.start();
		scheduler.scheduleJob(jobDetail,trigger);
	}
}

       建立定時任務:距離當前時間4秒之後執行之後每隔兩秒執行一次,距離當前時間6秒之後停止執行,程式碼如下:

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
	public static void main(String[] args) throws SchedulerException {
		// 建立一個JobDetail例項與HelloJob類繫結
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
		//列印當前時間
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("列印當前時間:"+sf.format(startTime));
		//獲取距離當前時間4秒之後的時間
		startTime.setTime(startTime.getTime()+4000L);
		// 建立一個Trigger例項,距離當前時間4秒鐘後執行任務,之後每隔兩秒執行一次任務
		//withRepeatCount方法引數:SimpleTrigger.REPEAT_INDEFINITELY永遠執行下去,若設定為具體數字則就執行幾次
		SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger().
				withIdentity("mtTrigger", "group1").startAt(startTime).
				withSchedule(SimpleScheduleBuilder.simpleSchedule().
				withIntervalInSeconds(2).withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY)).build();
		//建立scheduler例項
		SchedulerFactory sFactory = new StdSchedulerFactory();
		Scheduler scheduler = sFactory.getScheduler();
		scheduler.start();
		scheduler.scheduleJob(jobDetail,trigger);
	}
}

       建立定時任務:距離當前時間4秒之後執行之後每隔兩秒執行一次,永遠執行下去,程式碼如下:

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class HelloScheduler {
	public static void main(String[] args) throws SchedulerException {
		// 建立一個JobDetail例項與HelloJob類繫結
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
		//列印當前時間
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("列印當前時間:"+sf.format(startTime));
		//獲取距離當前時間4秒之後的時間
		startTime.setTime(startTime.getTime()+4000L);
		//獲取6秒之後的時間
		Date endDate = new Date();
		endDate.setTime(endDate.getTime()+6000L);
		/**
		 * 建立一個Trigger例項,距離當前時間4秒鐘後執行任務,之後每隔兩秒執行一次任務,距離當前6秒之後停止執行
		 * withRepeatCount方法引數:SimpleTrigger.REPEAT_INDEFINITELY永遠執行下去,若設定為具體數字則就執行幾次
		 * 任務只執行兩次,由此可見endDate條件是優先於withRepeatCount
		 */
		SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger().
				withIdentity("mtTrigger", "group1").startAt(startTime).endAt(endDate).
				withSchedule(SimpleScheduleBuilder.simpleSchedule().
				withIntervalInSeconds(2).withRepeatCount(5)).build();
		//建立scheduler例項
		SchedulerFactory sFactory = new StdSchedulerFactory();
		Scheduler scheduler = sFactory.getScheduler();
		scheduler.start();
		scheduler.scheduleJob(jobDetail,trigger);
	}
}

       注意:重複次數(withRepeatCount)可以為0、正整數或者是SimpleTrigger.REPEAT_INDEFINITELY常量值;重複的執行間隔必須為0或者長整數;一旦被制定了endTime引數,那麼它會覆蓋重複次數引數的效果。

3.淺談CronTrigger

      CornTrigger:基於日曆的作業排程器,而不是像SimpleTrigger那樣精確指定間隔時間,比SimpleTrigger更常用。基於Cron表示式,用於配置CronTrigger例項,是由7個子表示式組成的字串,描述了時間表的詳細資訊。格式: [秒] [分] [小時][日] [月] [周] [年],示例程式碼如下:

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
	public static void main(String[] args) throws SchedulerException {
		// 建立一個JobDetail例項與HelloJob類繫結
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
		//列印當前時間
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("列印當前時間:"+sf.format(startTime));
		//每秒鐘觸發一次任務
		CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger().
				withIdentity("mtTrigger", "group1").
				withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ? *")).
				build();
		//建立scheduler例項
		SchedulerFactory sFactory = new StdSchedulerFactory();
		Scheduler scheduler = sFactory.getScheduler();
		scheduler.start();
		scheduler.scheduleJob(jobDetail,trigger);
	}
}

      常用Corn表示式:

  • 2017年內每天10點15分觸發一次:0 15 10 ? * * 2017
  • 每天10點15分觸發:0 15 10 ? * *
  • 每天下午的2點到2點59分執行(整點開始,每隔5分鐘觸發):0 0/5 14 * * ?
  • 從週一到週五的每天上午10點15分觸發:0 15 10 ? * MON-FRI
  • 每月第三週的星期五(6#3:6代表星期五,#代表第)10點15分開始觸發:0 15 10 ? 6#3
  • 從2016年到2017年每月最後一週的星期五10點15分觸發:0 15 10 ? * 6L 2016-2017
  • 每天14點整至14點59分55秒及18點整至18點59分55秒,每5秒觸發一次:0/5 * 14,18 * * ?
  說明:'L'和'W'可以一起組合使用;周欄位英文字母不區分大小寫,即MON和mon意識相同;可以利用線上工具自動生成。

4.淺談Scheduler

      Scheduler——工廠模式:所有的Scheduler例項應該由SchedulerFactory來建立,一般包含:StdSchedulerFactory、DirectSchedulerFactory(引數資訊需要在程式碼中維護故不常用)。StdSchedulerFactory使用一組引數來建立和初始化Quartz排程器,配置引數一般儲存在quartz.properties檔案中,呼叫getScheduler方法就能建立和初始化排程器物件。Scheduler的主要函式:Data scheduleJob(JobDetail jobDetail,Trigger trigger);返回最近一次任務將要執行的時間,程式碼如下:

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
	public static void main(String[] args) throws SchedulerException {
		// 建立一個JobDetail例項與HelloJob類繫結
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
		//列印當前時間
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("列印當前時間:"+sf.format(startTime));
		//每天10點15分觸發:0 15 10 ? * *
		//每天下午的2點到2點59分執行(整點開始,每隔5分鐘觸發):0 0/5 14 * * ?
		//從週一到週五的每天上午10點15分觸發:0 15 10 ? * MON-FRI
		//每月第三週的星期五(6#3:6代表星期五,#代表第)10點15分開始觸發:0 15 10 ? 6#3
		//從2016年到2017年每月最後一週的星期五10點15分觸發:0 15 10 ? * 6L 2016-2017
		CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger().
				withIdentity("mtTrigger", "group1").
				withSchedule(CronScheduleBuilder.cronSchedule("0 15 10 ? * *")).
				build();
		//建立scheduler例項
		SchedulerFactory sFactory = new StdSchedulerFactory();
		Scheduler scheduler = sFactory.getScheduler();
		scheduler.start();
		System.out.println("Schedule time is:"+sf.format(scheduler.scheduleJob(jobDetail,trigger)));
	}
}

      void start();——啟動Scheduler;void standby();——將Scheduler暫時掛起,可以用start()繼續執行任務;void shutDown()關閉Scheduler且不能被重啟;示例程式碼如下:

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
	public static void main(String[] args) throws SchedulerException, InterruptedException {
		// 建立一個JobDetail例項與HelloJob類繫結
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
		//列印當前時間
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("列印當前時間:"+sf.format(startTime));
		//每秒鐘執行一次,Scheduler執行兩秒之後掛起,Scheduler掛起3秒之後重新啟動
		CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger().
				withIdentity("mtTrigger", "group1").
				withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ?")).
				build();
		//建立scheduler例項
		SchedulerFactory sFactory = new StdSchedulerFactory();
		Scheduler scheduler = sFactory.getScheduler();
		scheduler.start();
		System.out.println("Schedule time is:"+sf.format(scheduler.scheduleJob(jobDetail,trigger)));
		Thread.sleep(2000L);
		scheduler.standby();
		Thread.sleep(3000L);
		scheduler.start();
		/**
		 * shutDown()可以傳入一個Boolean型別的引數,若引數為true:表示等待所有正在執行的job執行完畢之後,再關閉scheduler
		 * 若引數為false,即和沒有傳入引數一樣,表示直接關閉scheduler,不管是否有Job正在執行
		 */
		scheduler.shutdown(); //關閉之後不可以重新開啟
		Thread.sleep(5000L);
		scheduler.start();//呼叫重新開啟丟擲異常:The Scheduler cannot be restarted after shutdown() has been called.
	}
}

      執行緒池屬性:threadCount——工作者執行緒的數目,最少為1,最大不超過100;threadPriority——設定執行緒池執行緒的優先順序,最小值為1,最大值為10,預設值為5;org.quartz.threadPool.class——org.quartz.simple.SimpleThreadPool;作業儲存設定——描述了在排程器例項的生命週期中,job和trigger資訊是如何被儲存的;外掛配置——滿足特定需求用到的Quartz外掛的配置。

5.Quartz實際應用

  • Spring配置Quartz作業的兩種方式:MethodInvokingJobDetailFactoryBean、JobDetailFactoryBean。