Quartz的介绍

一、什么是Quartz
1、quartz是一个作业调度系统(a job scheduling system),不但可以集成到其他软件系统中,而且还可以独立运行。
2、Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。Jobs可以做成标准的Java组件或 EJBs。
3、Quartz是一个任务日程管理系统,一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。借助于cron表达式,他可以执行各种复杂的任务调度。虽然JDK为简单任务调度提供了Timer支持,但对于更复杂的调度,如:在某个特定的时刻调度任务,Timer就力不从心了。
4、Quartz用一个小Java库发布文件(.jar文件),这个库文件包含了所有Quartz核心功能。这些功能的主要接口(API)是Scheduler接口。它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度。

二、下载和安装Quartz
1、Quartz的下载:http://www.quartz-scheduler.org/ (只有注册用户才能下载)
下载完成,将得到quartz-2.1.6.tar.gz,解压后得到的目录结构是:
doc : API 和 各种数据库的建表sql (纳尼?! 还和数据库有关系.)(⊙_⊙?) Quartz应用到集群,和持久化作业的时候会用到,先不讨论,咱入门先!

examples : 官方给写的例子了,也就是我们本次学习的重点

lib : Quartz 所依赖的jar , 相信你的工程中已经添加了吧 ,主要是 log c3p0 什么的,自己看看吧

quartz : 源码

…………

quartz-all-2.1.6.jar : 打好的 jar 包,将其放入工程的classpath路径下即可

三、javaSE中使用Quartz步骤
1、将quartz-all-2.1.6.jar或者quartz-2.1.6.jar添加到classpath路径下。
(实际上Quartz还是用SLF4J作为日志工具,因此还需要将slf4j-api-2.1.6.jar导入到类路径下)
2、配置quartz运行环境的基本属性文件:quartz.properties (放在类路径下即可)

[html] view plain copy
# 配置主调度器属性  
org.quartz.scheduler.instanceName=QuartzScheduler  
org.quartz.scheduler.instanceId=AUTO  
# 配置线程池  
# Quartz线程池的实现类  
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool  
# 线程池的线程数量  
org.quartz.threadPool.threadCount=1  
# 线程池里线程的优先级  
org.quartz.threadPool.threadPriority=10  
# 配置作业存储  
org.quartz.jobStore.misfireThreshold=60000  
<strong>org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore</strong>  

如果我们不配置此文件的话,默认使用quartz-2.1.6.jar中的quartz.properties文件(在该压缩文件的org/quartz路径下),如果需要改变其运行属性,我们可以自己创建一个quartz.properties文件,并将该文件放在系统加载的类路径下,ClassLoader就会自动加载并启用其中的各种属性。
3、创建quartz作业类
该类须实现org.quartz.Jog接口,该接口只有一个execute()方法,当quartz调度改作业运行时,execute()方法就会执行。

[java] view plain copy
package lee;  

import org.quartz.Job;  
import org.quartz.JobExecutionContext;  
import org.quartz.JobExecutionException;  
import java.util.*;  
public class TestJob  
    implements Job  
{  
    //判断作业是否执行的旗标  
    private boolean isRunning = false;  
    public void execute(JobExecutionContext context)   
        throws JobExecutionException  
    {  
        //如果作业没有被调度  
        if (!isRunning)  
        {  
            System.out.println(new Date() + "  作业被调度。");  
            //循环100次来模拟任务的执行  
            for (int i = 0; i < 100 ; i++)  
            {  
                System.out.println("作业完成" + (i + 1) + "%");  
                try  
                {  
                    Thread.sleep(100);  
                }  
                catch (InterruptedException ex)  
                {  
                    ex.printStackTrace();  
                }  
            }  
            System.out.println(new Date() + "  作业调度结束。");  
        }  
        //如果作业正在运行,即使获得调度,也立即退出  
        else  
        {  
            System.out.println(new Date() + "任务退出");  
        }  
    }  
}  

3、创建quartz触发器
触发器用来指定任务被调度的时机。该框架提供了一系列的触发器,但最常用的的是:SimpleTrigger和CronTrigger。
SimpleTrigger:主要用于简单的调度。如在给定的时间内重复执行作业或者间隔固定的时间执行作业。类似于JDK提供的Timer。
CronTrigger:用于执行更复杂的调度。该调度器基于Calendar—Like和Unix Corn的表达式。
如: //创建trigger,创建一个简单的调度器
//指定该任务被重复调度50次,每次间隔2秒
Trigger trigger = new SimpleTrigger(“dd” ,
Scheduler.DEFAULT_GROUP, 50, 20000) ;
4、创建quartz调度器
调度器用于将任务和触发器管理起来,任务和触发器是多对多的关系:当一个任务关联多个触发器时,每个触发器被激发时,这个任务都会被调度一次;当一个触发器控制多个任务时,此触发器被触发时,所有关联到给触发器的任务都将被调度。
quartz调度器由Schedule接口体现。该接口声明如下方法:
a:void addJob(JobDetail d,boolean replace):将jobDetail实例添加到调度器。
b:Date scheduleJob(JobDetail d,Trigger t):使用Trigger来控制JobDetail实例。
c:Date scheduleJob(Trigger t):添加触发器t来调度作业。


[java] view plain copy
package lee;  

import org.quartz.Scheduler;  
import org.quartz.Trigger;  
import org.quartz.impl.StdSchedulerFactory;  
import org.quartz.JobDetail;  
import org.quartz.SchedulerException;  
import org.quartz.SimpleTrigger;  
public class MyQuartzServer  
{  
    public static void main(String[] args)  
    {  
        MyQuartzServer server = new MyQuartzServer();  
        try  
        {  
            server.startScheduler();  
        }  
        catch (SchedulerException ex)  
        {  
            ex.printStackTrace();  
        }  
    }  
    //执行调度  
    private void startScheduler() throws SchedulerException   
    {  
        //使用工厂创建调度器实例  
        Scheduler scheduler = StdSchedulerFactory  
            .getDefaultScheduler();   
        //以作业创建JobDetail实例  
        JobDetail jobDetail = new JobDetail("dd",   
            Scheduler.DEFAULT_GROUP , TestJob.class);  
        //创建trigger,创建一个简单的调度器  
        //指定该任务被重复调度50次,每次间隔2秒  
        Trigger trigger = new SimpleTrigger("dd" ,   
            Scheduler.DEFAULT_GROUP, 50, 20000) ;  
        //调度器将作业与trigger关联起来  
        scheduler.scheduleJob(jobDetail, trigger );   
        //开始调度  
        scheduler.start();  
    }  
}  
简单触发器(SimpleTriggSimpleJob.Java
public class SimpleJob implements Job {  

    @Override  
    public void execute(JobExecutionContext context)  
            throws JobExecutionException {  
        // job 的名字  
        String jobName = context.getJobDetail().getKey().getName();  

        // 任务执行的时间  
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy 年 MM 月 dd 日  HH 时 mm 分 ss 秒");  
        String jobRunTime = dateFormat.format(Calendar.getInstance().getTime());  

        // 输出任务执行情况  
        System.out.println("任务 : " + jobName + " 在  " +jobRunTime + " 执行了 ");  
    }  
}  

在这里 对输出 的日期进行了一小下 格式化,适应国人习惯.

SimpleTriggerExample.java
[java] view plain copy
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.text.SimpleDateFormat;  
import java.util.Date;  

import org.quartz.DateBuilder;  
import org.quartz.DateBuilder.IntervalUnit;  
import org.quartz.JobDetail;  
import org.quartz.Scheduler;  
import org.quartz.SchedulerFactory;  
import org.quartz.SchedulerMetaData;  
import org.quartz.SimpleTrigger;  
import org.quartz.impl.StdSchedulerFactory;  

/** 
 * Simple Triggers (简单触发器) 的使用. 
 */  
public class SimpleTriggerExample {  

    public static void main(String[] args) throws Exception {  
        SimpleTriggerExample example = new SimpleTriggerExample();  
        example.run();  
    }  

    public void run() throws Exception {  
        // 日期格式化  
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy 年 MM 月 dd 日  HH 时 mm 分 ss 秒");  

        SchedulerFactory sf = new StdSchedulerFactory();  
        Scheduler sched = sf.getScheduler();  
        System.out.println("--------------- 初始化 -------------------");  

        // 下一个第15秒 例:  
        //           当前 10秒,则 执行时间为15秒  
        //           当前 16秒,则 执行时间为30秒  
        //           当前 33秒,则 执行时间为45秒  
        //           当前 48秒,则 执行时间为00秒  
        Date startTime = DateBuilder.nextGivenSecondDate(null, 15);  

        // job1 将只会执行一次   
        JobDetail job = newJob(SimpleJob.class).withIdentity("job1", "group1").build();  
        SimpleTrigger trigger = (SimpleTrigger) newTrigger()  
                .withIdentity("trigger1", "group1")  
                .startAt(startTime).build();  
        // 把job1 和 trigger加入计划   .  ft:此任务要执行的时间  
        Date ft = sched.scheduleJob(job, trigger);  
        System.out.println(job.getKey().getName() + " 将在 : " + dateFormat.format(ft) + " 时运行.并且重复: "  
                + trigger.getRepeatCount() + " 次, 每次间隔 "  
                + trigger.getRepeatInterval() / 1000 + " 秒");  

        // job2 将只会和执行一次(和job1一样一样的,吼~~)  
        job = newJob(SimpleJob.class).withIdentity("job2", "group1").build();  
        trigger = (SimpleTrigger) newTrigger()  
                .withIdentity("trigger2", "group1").startAt(startTime).build();  
        ft = sched.scheduleJob(job, trigger);  
        System.out.println(job.getKey().getName() + " 将在 : " + dateFormat.format(ft) + " 时运行.并且重复: "  
                + trigger.getRepeatCount() + " 次, 每次间隔 "  
                + trigger.getRepeatInterval() / 1000 + " 秒");  

        // job3 将执行11次(执行1次,重复10次) ,每10秒重复一次  
        job = newJob(SimpleJob.class).withIdentity("job3", "group1").build();  
        trigger = newTrigger()  
                .withIdentity("trigger3", "group1")  
                .startAt(startTime)  
                .withSchedule(  
                        simpleSchedule()  
                        .withIntervalInSeconds(10)// 重复间隔  
                        .withRepeatCount(10))     // 重复次数  
                        .build();  
        ft = sched.scheduleJob(job, trigger);  
        System.out.println(job.getKey().getName()+ " 将在 : " + dateFormat.format(ft) + " 时运行.并且重复: "  
                + trigger.getRepeatCount() + " 次, 每次间隔 "  
                + trigger.getRepeatInterval() / 1000 + " 秒");  


        // trigger3 改变了.  每隔10s重复.共重复2次  
        // 此处说明 , 上面job3已经 设定了 trigger3 重复10次,每次10s  
        //        在这里又改变了 trigger3的设置,不会对以前构成影响,而是当做一个新的来处理  
        trigger = newTrigger()  
                .withIdentity("trigger3", "group2")  
                .startAt(startTime)  
                .withSchedule(  
                        simpleSchedule()  
                        .withIntervalInSeconds(10)  
                        .withRepeatCount(2))  
                        .forJob(job).build();  
        ft = sched.scheduleJob(trigger);  
        System.out.println(job.getKey().getName() + " 改变过trigger3属性的job3 : " + dateFormat.format(ft) + " 时运行.并且重复: "  
                + trigger.getRepeatCount() + " 次, 每次间隔 "  
                + trigger.getRepeatInterval() / 1000 + " 秒");  

        // job5 将在5分钟后运行一次  
        job = newJob(SimpleJob.class).withIdentity("job5", "group1").build();  
        trigger = (SimpleTrigger) newTrigger()  
                .withIdentity("trigger5", "group1")  
                .startAt(futureDate(5, IntervalUnit.MINUTE)) // 设定5分钟后运行  
                .build();  
        ft = sched.scheduleJob(job, trigger);  
        System.out.println(job.getKey().getName()+ " 将在 : " + dateFormat.format(ft) + " 时运行.并且重复: "  
                + trigger.getRepeatCount() + " 次, 每次间隔 "  
                + trigger.getRepeatInterval() / 1000 + " 秒");  

        // job6  每40s运行一次,没有指定重复次数,则无下限的重复  
        job = newJob(SimpleJob.class).withIdentity("job6", "group1").build();  
        trigger = newTrigger()  
                .withIdentity("trigger6", "group1")  
                .startAt(startTime)  
                .withSchedule(  
                        simpleSchedule().withIntervalInSeconds(40)  
                                .repeatForever()).build();  
        ft = sched.scheduleJob(job, trigger);  
        System.out.println(job.getKey().getName() + " 将在 : " + dateFormat.format(ft) + " 时运行.并且重复: "  
                + trigger.getRepeatCount() + " 次, 每次间隔 "  
                + trigger.getRepeatInterval() / 1000 + " 秒");  

        // 所有的任务都被加入到了 scheduler中 ,但只有 schedulers.start(); 时才开始执行  
        sched.start();  
        System.out.println("------- 开始调度 (调用.start()方法) ----------------");  
        System.out.println("-------系统 启动 的 时间 :" + dateFormat.format(new Date()));  

        // 在 scheduled.start(); 之后,还可以将 jobs 添加到执行计划中  
        // job7 将重复20次 ,每5分钟重复一次  
        job = newJob(SimpleJob.class).withIdentity("job7", "group1").build();  
        trigger = newTrigger()  
                .withIdentity("trigger7", "group1")  
                .startAt(startTime)  
                .withSchedule(  
                        simpleSchedule()  
                        .withIntervalInMinutes(5) // 5分钟   
                        .withRepeatCount(20))     // 重复20.build();  
        ft = sched.scheduleJob(job, trigger);  
        System.out.println(job.getKey().getName() + " 将在 : " + dateFormat.format(ft) + " 时运行.并且重复: "  
                + trigger.getRepeatCount() + " 次, 每次间隔 "  
                + trigger.getRepeatInterval() / 1000 + " 秒");  

        // job8  可以立即执行. 无trigger注册  
        job = newJob(SimpleJob.class).withIdentity("job8", "group1")  
                .storeDurably().build();  
        sched.addJob(job, true);  
        System.out.println("手动触发  job8...(立即执行)");  
        sched.triggerJob(jobKey("job8", "group1"));  

        System.out.println("------- 等待30 秒... --------------");  

        try {  
            Thread.sleep(30L * 1000L);  
        } catch (Exception e) { }  

        // job7 将马上执行,重复10次,每秒一次  
        System.out.println("-------  重新安排 ... --------------------");  
        trigger = newTrigger()  
                .withIdentity("trigger7", "group1")  
                .startAt(startTime)  
                .withSchedule(  
                        simpleSchedule().withIntervalInMinutes(5)  
                                .withRepeatCount(20)).build();  

        ft = sched.rescheduleJob(trigger.getKey(), trigger);  
        System.out.println("job7 被重新安排 在 : " + dateFormat.format(ft) +"  执行. \r   当前时间 :" + dateFormat.format(new Date())+"预定执行时间已过,任务立即执行");  

        try {  
            System.out.println("------- 等待5分钟  ... ------------");  
            Thread.sleep(300L * 1000L);  
        } catch (Exception e) { }  

        sched.shutdown(true);  
        System.out.println("------- 调度已关闭 ---------------------");  

        // 显示一下  已经执行的任务信息  
        SchedulerMetaData metaData = sched.getMetaData();  
        System.out.println("~~~~~~~~~~  执行了 " + metaData.getNumberOfJobsExecuted() + " 个 jobs.");  

    }  

}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值