任务调度 Quartz

来源:互联网 发布:淘宝上购买飞行燃料 编辑:程序博客网 时间:2024/06/15 17:48

一、 Quartz 的原理:

Quartz 设计的核心类包括Scheduler(调度器), Job (任务)以及 Trigger(触发器)。其中,Job 负责定义需要执行的任务,Trigger 负责设置调度策略,Scheduler 将二者组装在一起,并触发任务开始执行。

二、 Quartz 的优点:

1、job 与 Trigger 的松耦合同一个 Job 可以绑定多个不同的 Trigger,同一个Trigger不可以绑定多个job;可以修改或者替换Trigger,而不用重新定义与之关联的Job,灵活性很强。

2、提供了 listener 的功能:主要包含三种 listener:JobListener,TriggerListener 以及 SchedulerListener。当系统发生故障,相关人员需要被通知时,Listener 便能发挥它的作用。最常见的情况是,当任务被执行时,系统发生故障,Listener 监听到错误,立即发送邮件给管理员

3、持久化:即将任务调度的相关数据保存下来。默认情况 下,Quartz 采用的是 org.quartz.simpl.RAMJobStore,在这种情况下,数据仅能保存在内存中,系统重启后会全部丢失。若想持久化数据,需要采用 org.quartz.simpl.JDBCJobStoreTX。

三、 Quartz 下载、安装、配置:

1、下载quartz 2.2.3.tar.gz:http://d2zwv9pap9ylyd.cloudfront.net/quartz-2.2.3-distribution.tar.gz

2、jar包引入

a、maven项目引:

<!-- quartz 任务调度 --><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.3</version></dependency><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>2.2.3</version></dependency>
b、普通项目:如果你希望在很多应用中使用quartz,将quartz的jar包放在应用服务器的classpath下即可。如果你只是希望在独立的应用中使用quartz,将quartz的jar包和你的应用依赖的其它jar包放在一起即可。
四、 Quartz 相关类介绍:

1、Job:是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。Job运行时的信息保存在JobDataMap实例中;
2、Trigger:是一个类,描述触发Job执行的时间触发规则。主要有SimpleTrigger和CronTrigger这两个子类。SimpleTrigger:当仅需触发一次或者以固定时间间隔周期执行;CronTrigger:可以通过Cron表达式定义出各种复杂时间规则的调度方案:如每早晨9:00执行,周一、周三、周五下午5:00执行等;

3、Scheduler:代表一个Quartz的独立运行容器,Trigger和JobDetail可以注册到Scheduler中,两者在Scheduler中拥有各自的组及名称,组及名称是Scheduler查找定位容器中某一对象的依据,Trigger的组及名称必须唯一,JobDetail的组和名称也必须唯一(但可以和Trigger的组和名称相同,因为它们是不同类型的)。Scheduler可以将Trigger绑定到某一JobDetail中,这样当Trigger触发时,对应的Job就被执行。

4、JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息,JobDetail承担了这一角色。

5、Calendar:org.quartz.Calendar和java.util.Calendar不同,它是一些日历特定时间点的集合(可以简单地将org.quartz.Calendar看作java.util.Calendar的集合——java.util.Calendar代表一个日历时间点,无特殊说明后面的Calendar即指org.quartz.Calendar)。一个Trigger可以和多个Calendar关联,以便排除或包含某些时间点。

6、ThreadPool:Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。

五、 Quartz 的使用:

import static org.quartz.DateBuilder.futureDate;import static org.quartz.JobBuilder.newJob;import static org.quartz.JobKey.jobKey;import static org.quartz.SimpleScheduleBuilder.simpleSchedule;import static org.quartz.TriggerBuilder.newTrigger;import java.util.Date;import org.quartz.DateBuilder.IntervalUnit;import org.quartz.Job;import org.quartz.JobDetail;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SchedulerMetaData;import org.quartz.SimpleTrigger;import org.quartz.impl.StdSchedulerFactory;public class QuartzController implements Job {    @Override    public void execute(JobExecutionContext arg0) throws JobExecutionException {        System.out.println("yyx's jobTest:Description=" + arg0.getJobDetail().getKey() + ",type=" + arg0.getJobDetail().getJobDataMap().get("type"));        System.out.println(new Date());    }    public static void main(String[] args) {        try {            // 创建调度器            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();            scheduler.start();//调度开启            // 创建该Job负责定义需要执行任务            JobDetail job1 = newJob(QuartzController.class).withIdentity("job1", "group1").usingJobData("type", "yyx1").build();            // 创建触发器立即执行 默认执行一次            SimpleTrigger trigger1 = (SimpleTrigger) newTrigger().withIdentity("myTrigger1", "group1").startNow().build();            Date df = scheduler.scheduleJob(job1, trigger1);// 执行一次            // 立即执行 5s一次执行5次            JobDetail job2 = newJob(QuartzController.class).withIdentity("job2", "group1").usingJobData("type", "yyx2").build();            SimpleTrigger trigger2 = newTrigger().withIdentity("myTrigger2", "group2").startNow().withSchedule(simpleSchedule().withIntervalInSeconds(5).withRepeatCount(5)).build();            df = scheduler.scheduleJob(job2, trigger2);            // 给触发器绑定任务forJob(job3)            JobDetail job3 = newJob(QuartzController.class).withIdentity("job3", "group1").usingJobData("type", "yyx3").build();            SimpleTrigger trigger3 = newTrigger().withIdentity("myTrigger3", "group3").startNow().withSchedule(simpleSchedule().withIntervalInSeconds(5).withRepeatCount(5)).forJob(job3).build();            df = scheduler.scheduleJob(job3, trigger3);            // 设定5分钟后运行futureDate(5, IntervalUnit.MINUTE)            JobDetail job4 = newJob(QuartzController.class).withIdentity("job4", "group1").usingJobData("type", "yyx4").build();            SimpleTrigger trigger4 = (SimpleTrigger) newTrigger().withIdentity("trigger4", "group4").startAt(futureDate(5, IntervalUnit.MINUTE)).build();            df = scheduler.scheduleJob(job4, trigger4);            // 一直执行repeatForever()            JobDetail job5 = newJob(QuartzController.class).withIdentity("job5", "group1").usingJobData("type", "yyx5").build();            SimpleTrigger trigger5 = newTrigger().withIdentity("myTrigger5", "group5").startNow().withSchedule(simpleSchedule().withIntervalInSeconds(5).repeatForever()).build();            df = scheduler.scheduleJob(job5, trigger5);            // 手动触发 storeDurably:是否有触发器            JobDetail job6 = newJob(QuartzController.class).withIdentity("job6", "group1").storeDurably().build();            scheduler.addJob(job6, true);            scheduler.triggerJob(jobKey("job6", "group1"));            try {                Thread.sleep(5 * 60 * 1000);// 等待5分钟            } catch (InterruptedException e) {                e.printStackTrace();            }            scheduler.shutdown();// 关闭调度            SchedulerMetaData meta = scheduler.getMetaData();            System.out.println("已经执行的job个数:" + meta.getNumberOfJobsExecuted());        } catch (SchedulerException e) {            e.printStackTrace();        }        }}

注意:同一个Trigger不可以绑定多个job,如下代码运行时会报下面的错误。

try {                scheduler.scheduleJob(job1, trigger1);                Thread.sleep(2 * 1000);                scheduler.scheduleJob(job2, trigger1);                Thread.sleep(2 * 1000);                scheduler.scheduleJob(job3, trigger1);            } catch (InterruptedException e) {                e.printStackTrace();            }


参考文献:

1、http://www.quartz-scheduler.org/documentation/quartz-2.2.x/quick-start.html

2、http://ifeve.com/quartz-tutorial-job-jobdetail/

3、http://7-sun.com/doc/quartz1.8/org/quartz/package-summary.html


0 0
原创粉丝点击