任務調度
在企業級應用中,經常會制定一些“計劃任務”,即在某個時間點做某件事情 核心是以時間為關注點,即在一個特定的時間點,系統執行指定的一個操作 任務調度涉及多線程並發、線程池維護、運行時間規則解析、運行現場的保護以恢復等方面 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();
上面的例子,基本算是完成了任務調度。
期待 第二版