初识Quartz(二)

原创
2014/01/27 22:18
阅读数 3.7K

    这篇文章将是年前的最后一篇,明天就要回家了,在此祝愿OSC的各位coder新年快乐,完事如意!

简单作业:

package quartz_project.example2;

import java.util.Date;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 需要在特定的日期或者时间启动,
 * 并且期望以一个可能的间隔时间重复执行 n 次的Job
 * 
 * @author caijw
 */
public class SimpleJob implements Job {
    
    private static Logger _log = LoggerFactory.getLogger(SimpleJob.class);

    @Override
    public void execute(JobExecutionContext ctx) throws JobExecutionException {
        JobKey jobKey = ctx.getJobDetail().getKey();
        _log.info("SimpleJob says: " + jobKey + " executing at " + new Date());
    }

}

:由于代码较长,本文将按照任务分开解释,第一段代码将做为下列任务的运行环境。

Logger log = LoggerFactory.getLogger(SimpleTriggerExample.class);

log.info("----- Initializing --------");
//第一步我们必须获取一个调度器
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();

log.info("----- Initialization complete -------");

//作业的执行时间(这里需要注意,下面详细说明)
Date startTime = DateBuilder.nextGivenSecondDate(null, 15);

log.info("----- scheduling jobs --------");

    注意:Date startTime = DateBuilder.nextGivenSecondDate(null, 15);

        每分钟以15秒为单位,在当前时间的在下一个15秒开始。例如:当前时间为18:20:02秒,那么作业将在18:20:15秒执行。

一、在startTime时间点执行job1

JobDetail job = JobBuilder.newJob(SimpleJob.class)
    .withIdentity("job1", "group1")
    .build();

SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
    .withIdentity("trigger1", "group1")
    .startAt(startTime).build(); //该触发器将在startTime时执行作业

Date ft = sched.scheduleJob(job, trigger);

log.info(job.getKey() + " will run at: " + ft +
        " and repeat: " + trigger.getRepeatCount() + 
        " times, every " + trigger.getRepeatInterval() / 1000 + " seconds");

二、在startTime时间点执行job2

job = JobBuilder.newJob(SimpleJob.class)
    .withIdentity("job2", "group1")
    .build();

trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
    .withIdentity("trigger2", "group1")
    .startAt(startTime).build();

ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft +
        " and repeat: " + trigger.getRepeatCount() + 
        " times, every " + trigger.getRepeatInterval() / 1000 + " seconds");

   通过下面的输出结果可以发现:该作业是以多线程并发运行的

[INFO] 27 一月 09:19:15.000 下午 DefaultQuartzScheduler_Worker-2 [quartz_project.example2.SimpleJob]
SimpleJob says: group1.job1 executing at Mon Jan 27 21:19:15 CST 2014

[INFO] 27 一月 09:19:15.000 下午 DefaultQuartzScheduler_Worker-3 [quartz_project.example2.SimpleJob]
SimpleJob says: group1.job2 executing at Mon Jan 27 21:19:15 CST 2014

三、在startTime时间点执行job3,以后每隔10s运行一次,重复10次,共运行11次。

job = JobBuilder.newJob(SimpleJob.class)
    .withIdentity("job3", "group1")
    .build();

trigger = TriggerBuilder.newTrigger()
    .withIdentity("trigger3", "group1")
    .startAt(startTime)
    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
            .withIntervalInSeconds(10) //时间间隔10s
            .withRepeatCount(10)) //重复次数10次
    .forJob(job).build();

ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft +
        " and repeat: " + trigger.getRepeatCount() + 
        " times, every " + trigger.getRepeatInterval() / 1000 + " seconds");

三、为job3重新绑定trigger,在startTime时间点执行job3,以后每隔10s运行一次,重复2次。

trigger = TriggerBuilder.newTrigger()
    .withIdentity("trigger3", "group2") //记得换成group2不然就不唯一了
    .startAt(startTime)
    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
            .withIntervalInSeconds(10)
            .withRepeatCount(2))
    .forJob(job).build();
ft = sched.scheduleJob(trigger); //注意这里,不可以使用sched.scheduleJob(job, trigger)
log.info(job.getKey() + " will [also] run at: " + ft +
        " and repeat: " + trigger.getRepeatCount() + 
        " times, every " + trigger.getRepeatInterval() / 1000 + " seconds");

四、在当前时间的5分钟后执行job5。

job = JobBuilder.newJob(SimpleJob.class)
    .withIdentity("job5", "group1")
    .build();

trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
    .withIdentity("trigger5", "group1")
    .startAt(DateBuilder.futureDate(5, IntervalUnit.MINUTE)) //当前时间的5分钟后
    .build();

ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft +
        " and repeat: " + trigger.getRepeatCount() + 
        " times, every " + trigger.getRepeatInterval() / 1000 + " seconds");

五、在startTime时间点执行job6,以后每隔40s运行一次,无限执行下去。

job = JobBuilder.newJob(SimpleJob.class)
    .withIdentity("job6", "group1")
    .build();

trigger = TriggerBuilder.newTrigger()
    .withIdentity("trigger6", "group1")
    .startAt(startTime)
    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
            .withIntervalInSeconds(40)
            .repeatForever()) //无限次
    .forJob(job).build();

ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft +
        " and repeat: " + trigger.getRepeatCount() + 
        " times, every " + trigger.getRepeatInterval() / 1000 + " seconds");

六、所有的作业都被加到了调度器中,但是只有调度器启动作业才会开始执行

log.info("------ starting scheduler -------");
sched.start();//启动调度器
log.info("------ started scheduler -------");

七、在调度器启动后,仍可以添加作业进去:在startTime时间点执行job7,以后每隔5分钟运行一次,执行20次。

job = JobBuilder.newJob(SimpleJob.class)
    .withIdentity("job7", "group1")
    .build();

trigger = TriggerBuilder.newTrigger()
    .withIdentity("trigger7", "group1")
    .startAt(startTime)
    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
            .withIntervalInMinutes(5)
            .withRepeatCount(20))
    .build();

ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft +
        " and repeat: " + trigger.getRepeatCount() + 
        " times, every " + trigger.getRepeatInterval() / 1000 + " seconds");

八、作业可以不需要触发器,而是通过手动启动。

job = JobBuilder.newJob(SimpleJob.class)
    .withIdentity("job8", "group1")
    .storeDurably() //即使没有Trigger关联时,也不需要删除该JobDetail
    .build();

sched.addJob(job, true);

log.info("'Manually' triggering job8...");
sched.triggerJob(JobKey.jobKey("job8", "group1"));//通过手动触发,执行作业8

九、重新注册job7,利用线程休眠模拟过了执行时间,效果就是该作业会马上执行一次。

log.info("------- Waiting 30 seconds... --------------");

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

log.info("---------- rescheduling... -------");
trigger = TriggerBuilder.newTrigger()
    .withIdentity("trigger7", "group1")
    .startAt(startTime)
    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
            .withIntervalInMinutes(5)
            .withRepeatCount(20))
    .build();

ft = sched.rescheduleJob(trigger.getKey(), trigger);
log.info("job7 rescheduled to run at: " + ft);

    注意: ft = sched.rescheduleJob(trigger.getKey(), trigger); 表示在sched.start()之后调用,可以在job开始后重新定义trigger,然后重新注册。

十、五分钟后关闭调度器,所以没有执行完的作业将终止。

log.info("------- Waiting five minutes... ------------");
try {
    // wait five minutes to show jobs
    Thread.sleep(300L * 1000L); 
    // executing...
} catch (Exception e) {
}

log.info("------- Shutting Down ---------------------");

sched.shutdown(true);

log.info("------- Shutdown Complete -----------------");

十一、查看这段时间内,总执行了多少任务。

SchedulerMetaData metaData = sched.getMetaData();
log.info("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");


展开阅读全文
打赏
2
24 收藏
分享
加载中
2
2014/02/06 17:09
回复
举报
1
2014/02/06 17:08
回复
举报
更多评论
打赏
2 评论
24 收藏
2
分享
返回顶部
顶部