任務調度
在企業級應用中,經常會制定一些“計劃任務”,即在某個時間點做某件事情 核心是以時間為關注點,即在一個特定的時間點,系統執行指定的一個操作 任務調度涉及多線程並發、線程池維護、運行時間規則解析、運行現場的保護以恢復等方面 Quartz框架是一個開源的企業級任務調度服務,已經被作為任務調度的良好解決方案.

Quartz框架核心
Quartz對任務調度進行了高度抽象,提出了3個核心概念,並在org.quartz包中通過接口和類進行了描述 任務:就是執行的工作內容。Quartz提供Job接口來支持任務定義 觸發器:定義觸發Job執行的時間觸發規則。Quartz提供Trigger類及其子類支持觸發器功能, 調度器:Quartz提供了Scheduler接口,將工作任務和觸發器綁定,保證任務可以在正確的時間執行
運行環境

任務調度


任務執行
任務持久化

事務

集群

監聽器和插進

下面我們直接來看例子
我們創建一個計劃類 Plan
開始創建entity實體層定義任務的模板
public class Plan {
private String date;//時間
private String task;//任務
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Plan [date=" + date + ", task=" + task + "]";
}
public Plan() {
super();
// TODO Auto-generated constructor stub
}
public Plan(String date, String task) {
super();
this.date = date;
this.task = task;
}
我們創建一個提醒服務類RemindService
定制一個泛型集合用戶存儲多個Plan對象,提供一個方法讀取該泛型集合中的data
*/
public class RemindService {
public void printPlan(String userName){
List<Plan> plansFormToday=getPlansFormToday(userName);
System.out.println(userName+"//");
for (Plan plan : plansFormToday) {
System.out.println(plan+"\\\\");
}
}
private List<Plan> getPlansFormToday(String userName) {
//模擬數據庫查詢,僅說明問題
List<Plan> list=new ArrayList<Plan>();
list.add(new Plan("2016-11-3 14:31:11","陶研會|地點:會議室C01"));
list.add(new Plan("2016-11-3 14:31:20","總裁辦公室|地點:總裁辦公室"));
return list;
}
我們創建一個任務調度類RemindJob
/**
* 提醒業務類
* @author Admin
*
*/
public class RemindJob implements Job {
private RemindService service=new RemindService();
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
service.printPlan("你好!");
}
/**
* @return the service
*/
public RemindService getService() {
return service;
}
/**
* @param service the service to set
*/
public void setService(RemindService service) {
this.service = service;
}
核心代碼解析:

Job接口中只有一個 execute()方法,在實現類中 實現該方法以執行具體任務。



通過參數 JobExecutionContext 可以獲取調度上下文的各 種信息,如:任務名稱等

在原RemindJob的execute()方法中添加以下代碼,可以獲取該任務的名稱、 綁定的觸發器的名稱和每次任務觸發時間
//獲取用戶信息
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String value = (String)dataMap.get("happykey");
System.out.println(value);
System.out.println("TriggerName\t"+context.getTrigger().getKey().getName());
System.out.println("JobName\t"+context.getJobDetail().getKey().getName());
真正的任務對象和觸發器對象 Test
public class Test {
public static void main(String[] args) throws SchedulerException {
doRemind();
}
public static void doRemind() throws SchedulerException{
JobDetail job = JobBuilder.newJob(RemindJob.class)
.withIdentity("job1", "group1").build();//創建一個任務
/**
* 創建觸發器
* 第一種方式 不太好
*/
/*SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "myTriggerGroup").
withSchedule(SimpleScheduleBuilder.simpleSchedule().
withIntervalInSeconds(3).
repeatForever()).
startAt(new Date(System.currentTimeMillis()+1000)).build();*/
/**
* 創建觸發器
* 第二種 方式 非常好
* 可以 好用 2013年每月的第三個星期五上午10:30觸發 0 30 10 ? * 6#3 2013
* 2016年每月的第一個星期四下午16:17觸發 0 17 16 ? * 5#1 2016
* 每天15點到16點每5分鐘運行一次,此外,每天17點到18點每5分鐘運行一次
*/
CronTrigger trigger=TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "myTriggerGroup")
.withSchedule(CronScheduleBuilder.cronSchedule("0 18 16 ? * 5#1 2016")).build();
SchedulerFactory sf=new StdSchedulerFactory();//創建調度者工廠
Scheduler scheduler = sf.getScheduler();//創建一個調度者
scheduler.scheduleJob(job,trigger);//注冊並進行調度
scheduler.start();//啟動調度
//Thread.sleep(millis)
//scheduler.shutdown();//關閉調度
}
核心代碼解析:

這是通過JobDetail創建一個任務實例。

還可以通過JobDetail的JobDataMap對象來進行初始數據的設置,如傳入需要提醒的用戶姓名
public class TestJob {
public void doRemind() throws SchedulerException, InterruptedException {
JobDetail job = new JobDetail("remindJob", "group1", RemindJob.class);
// 獲取和任務關聯的JobDataMap對象
JobDataMap dataMap = job.getJobDataMap();
dataMap.put("user", "張三"); // 在JobDataMap對象中設置用戶數據
// 省略原有程序代碼
}
}

JobBuilder類

使用SimpleTrigger創建一個觸發器
SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "myTriggerGroup").
withSchedule(SimpleScheduleBuilder.simpleSchedule().
withIntervalInSeconds(3).
repeatForever()).
startAt(new Date(System.currentTimeMillis()+1000)).build();
創建一個調度器
SchedulerFactory sf=new StdSchedulerFactory();//創建調度者工廠
Scheduler scheduler = sf.getScheduler();//創建一個調度者
注冊任務和觸發器
scheduler.scheduleJob(job,trigger);//注冊並進行調度
scheduler.start();//啟動調度
啟動和關閉調度
sched.start(); sched.shutdown();
上面的例子,基本算是完成了任務調度。
期待 第二版