全面解析JAVA中的任务调度机制
2015-10-28 21:31
453 查看
任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务。JAVA中的任务调度主要包含以下3种:1、Timer2、ScheduledExecuror3、开源工具包Quartz一、Timer java.util.Timer是一种最简单的任务调度机制,使用Timer 实现任务调度的核心类是 Timer 和 TimerTask。其中 Timer 负责设定 TimerTask 的起始与间隔执行时间。使用者只需要创建一个 TimerTask 的继承类,实现自己的run 方法,然后将其丢给 Timer 去执行即可。Timer的设计核心是一个 TaskList 和一个 TaskThread。Timer 将接收到的任务丢到自己的 TaskList中,TaskList 按照 Task 的最初执行时间进行排序。TimerThread在创建 Timer 时会启动成为一个守护线程。这个线程会轮询所有任务,找到一个最近要执行的任务,然后休眠,当到达最近要执行任务的开始时间点,TimerThread 被唤醒并执行该任务。之后 TimerThread 更新最近一个要执行的任务,继续休眠。Timer的优点在于简单易用,但由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务。例子:
package com.lza.taskSchedule; import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class TimerTest extends TimerTask{ private String jobName=""; public TimerTest(String jobName){ super(); this.jobName=jobName; } @Override public void run(){//覆写执行方法 System.out.println("execute "+jobName+new Date()); } public static void main(String[] args){ Timer timer=new Timer(); long delay1=1*1000; long period1=1000; timer.schedule(new TimerTest("Job1"),delay1,period1);//从现在开始 1 秒后 每隔1秒 执行1次Job1 long delay2=2*1000; long period2=2000; timer.schedule(new TimerTest("Job2"),delay2,period2);//从现在开始 2 秒后 每隔2秒 执行1次Job2 } }二、ScheduledExecutorScheduledExecutor的设计思想是:每一个被调度的任务都会由线程池中一个线程去执行,因此任务是并发执行的,相互之间不会受到干扰。需要注意的是,只有当任务的执行时间到来时,ScheduedExecutor才会真正启动一个线程,其余时间 ScheduledExecutor 都是在轮询任务的状态。 ScheduledExecutorService 中两种最常用的调度方法 ScheduleAtFixedRate 和 ScheduleWithFixedDelay。ScheduleAtFixedRate 每次执行时间为上一次任务开始起向后推一个时间间隔,即每次执行时间为 :initialDelay,initialDelay+period, initialDelay+2*period, …; ScheduleWithFixedDelay 每次执行时间为上一次任务结束起向后推一个时间间隔,即每次执行时间为:initialDelay, initialDelay+executeTime+delay, initialDelay+2*executeTime+2*delay。ScheduleAtFixedRate 是基于固定时间间隔进行任务调度, ScheduleWithFixedDelay 取决于每次任务执行的时间长短,是基于不固定时间间隔进行任务调度。例子:
package com.lza.taskSchedule; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledExecutorTest implements Runnable { private String jobName = ""; public ScheduledExecutorTest(String jobName) { super(); this.jobName = jobName; } @Override public void run() { System.out.println("execute " + jobName); } public static void main(String[] args) { ScheduledExecutorService service = Executors.newScheduledThreadPool(10); long delayTime = 1; long period = 1; // 从现在开始1秒钟之后,每隔1秒钟执行一次job1 service.scheduleAtFixedRate(//固定时间间隔 new ScheduledExecutorTest("job1"), delayTime, period, TimeUnit.SECONDS); long delayTime2 = 2; long period2 = 2; // 从现在开始2秒钟之后,每隔2秒钟执行一次job2 service.scheduleWithFixedDelay(//不固定时间间隔 new ScheduledExecutorTest("job2"), delayTime2, period2, TimeUnit.SECONDS); } }三、开源工具包QuartzQuartz是一个强大的开源定时调度器,它主要由四部分构成:1、Job 表示工作也就是具体要执行的内容接口,这个接口只有一个方法void execute(JobExecutionContext context)2、JobDetail 表示一个具体的可执行的调度程序,而Job就是这个可执行调度程序所要执行的内容。另外JobDetail还包含了这个任务调度的方案和策略。3、Trigger 触发器 用来定义任务调度的时间与间隔、频率等。4、Scheduler 代表一个调度容器,一个调度容器可以注册多个JobDetail和Trigger。然后将它们组合在一起就可以用Scheduler容器进行调度了。整个Quartz的工作原理就是通过Scheduler这个容器去存储众多的JobDetail和Trigger,当容器启动后,由Trigger自动触发 去执行相应的JobDetailJobDetail本身就是一个可以执行的工作,Trigger则控制系统什么时候 按什么策略去调用JobDetail执行,而Scheduler的作用只是把它们两个组装在一起。在Scheduler这个容器中,通过线程池去对各个Job进行并行调度,提高容器的工作效率。例子:
package com.lza.taskSchedule; import java.util.Date; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * 构建一个Job类 这个类就是任务具体执行的操作类 * @author Administrator * */ public class TimerJob implements Job{ @Override public void execute(JobExecutionContext context) throws JobExecutionException { // TODO Auto-generated method stub System.out.println("Generating report - " + context.getJobDetail().getFullName() + ", " + context.getJobDetail().getJobDataMap().get("name") + context.getJobDetail().getJobDataMap().get("age")); System.out.println(new Date().toString()); } }
package com.lza.taskSchedule; import java.util.Map; import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.impl.StdSchedulerFactory; public class QuartzManager { private Scheduler scheduler; private final static String JOB_GROUP_NAME="TestJob"; private final static String TRIGGER_GROUP_NAME="TestTrigger"; private static QuartzManager instance = new QuartzManager(); public static QuartzManager getInstance(){ return instance; } public void init( ){ try { scheduler=new StdSchedulerFactory().getScheduler(); scheduler.start(); } catch (SchedulerException e) { System.out.println("schedule start fail:"+e); } } public QuartzManager(){ init(); } public boolean addJob(String jobName, String jobClass, String time ,Map<Object,Object> params) { boolean result = false; try { JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, Class.forName(jobClass));// 任务名,任务组,任务执行类 jobDetail.getJobDataMap().putAll(params); // 触发器 CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组 trigger.setCronExpression(time);// 触发器时间设定 if(scheduler.isShutdown()){ init( ); } scheduler.scheduleJob(jobDetail, trigger); result = true; } catch (Exception e) { result = false; System.out.println("schedule addJob fail jobName = " + jobName + ". time = " + time + ". jobClass = " + jobClass); } return result; } }
package com.lza.taskSchedule; import java.util.HashMap; import java.util.Map;
public class QuartzTest { public static void main(String args[]){ //TestJob testJob=new TestJob("Hello",21); Map<String,Object> testMap=new HashMap<String,Object>(); testMap.put("name", "Hello"); testMap.put("age", 21); boolean result=QuartzManager.getInstance().addJob("testId",TimerJob.class.getName() ,"0 36 15 28 10 ?", (Map)testMap); System.out.println(result); } }
参考链接:https://www.ibm.com/developerworks/cn/java/j-lo-taskschedule/
http://lavasoft.blog.51cto.com/62575/181907/
相关文章推荐
- java多线程并发executorservice(任务调度)类
- java使用任务架构执行任务调度示例
- python任务调度实例分析
- java定时调度器(Quartz)使用实例
- quartz实现定时功能实例详解(servlet定时器配置方法)
- Spring3.2.0和Quartz1.8.6集群配置
- quartz.2.1.x任务调度
- JFinal 整合Quartz
- JFinal Quartz 支持配置文件和持久化
- quartz的简单实现
- jfinal-quartz 使用jfinal启动quartz执行定时任务
- Spark 性能相关参数配置详解-任务调度篇
- Quartz定时调度时间配置格式说明与实例
- 任务调度的使用crontab
- spring任务实时调度的几个方法
- Quartz Core 图层编程
- 几种任务调度的 Java 实现方法与比较
- 关于Quartz的配置
- spirng-quartz定时任务简单实用
- iOS开发 — Quartz 2D基本使用