Quartz的简单使用

一、Quartz 介绍

Quartz是Java领域最著名的、功能丰富的、开放源码的作业调度工具,几乎可以在所有的Java应用程序中集成——从小的单机应用到大的电子商务系统。 Quartz可以用来执行成百上千甚至数万的级别的、简单或者复杂的作业调度,一个Job可以执行任意的你所编程的任务。 Quartz调度包括许多企业级功能,如JTA事务和集群支持。

Quartz的主要角色有:

  1. Job:被调度的任务,重写其中execute方法,每次调度时会执行该方法;
  2. JobDetail:一个Job的具体化,可以这么看,JobDetail = Job + JobData
  3. Scheduler:调度器
  4. SchedulerFactory:调度工厂
  5. 各种ScheduleBuilder:CronScheduleBuilder(支持cron表达式的调度器)、CalendarIntervalScheduleBuilder(支持时间间隔的调度器)、SimpleScheduleBuilder(最简单的触发器,可以设置间隔,重复次数)
  6. Trigger:触发器,用于定义任务调度和时间规则,可以这么看,Trigger = ScheduleBuilder + Time

每个JobDetail都可以被唯一标识且指定一个抽象的Job,每个Trigger也都可以被唯一标识,Scheduler将JobDetail和Trigger绑定在了一起,即当trigger发生时,会调用JobDetail对应的Job的execute方法。

可以看一下这篇博文的对Quartz 简单介绍:

http://qiaowei.xyz/2016/05/11/Java%E4%BD%BF%E7%94%A8quartz%E5%AE%9E%E7%8E%B0%E4%BD%9C%E4%B8%9A%E8%B0%83%E5%BA%A6/#

另外,还可以看看并发编程网上的系列教程:http://ifeve.com/quartz-tutorial-using-quartz/

二、项目实战

项目使用到的代码,简单地罗列一下。

1.获取Scheduler的工具类

public class QuartzScheduleUtils {

    private static Logger logger = LoggerFactory.getLogger(QuartzScheduleUtils.class);

    private volatile static Scheduler scheduler;

    public static Scheduler getInstanceScheduler(){
        if(scheduler == null){
            synchronized (QuartzScheduleUtils.class){
                if (scheduler == null) {
                    SchedulerFactory sf = new StdSchedulerFactory();
                    try {
                        scheduler = sf.getScheduler();
                    } catch (SchedulerException e) {
                        logger.error("获取Schedule时抛错:", e);
                    }
                }
            }
        }
        return scheduler;
    }
}

2.命名相关的工具类

public class ScheduleNameUtils {

    public static String getJobName(String taskSubId){
        return taskSubId + "Job";
    }

    public static String getTriggerName(String taskSubId){
        return taskSubId + "Trigger";
    }

    public static String getGroupName(String taskId){
        return "group_" + taskId;
    }
}

3.实现Job

这里需要实现org.quartz.Job接口,实现execute方法

public class ScheduleJob implements Job {

    private static final Logger LOG = LoggerFactory.getLogger(ScheduleJob.class);

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
        String json = jobDataMap.getString("taskInfoDtoJson");
        if (StringUtils.isBlank(json)) {
            return;
        }
        // TODO: what you want to do.
    }
}

4.执行定时任务

    public void doJob() throws Exception {
        Scheduler scheduler = QuartzScheduleUtils.getInstanceScheduler();
        scheduler.start();
        JobDetail job = JobBuilder.newJob(ScheduleJob.class)
                .withIdentity(ScheduleNameUtils.getJobName(this.getTaskSubId())
                        , ScheduleNameUtils.getGroupName(this.getTaskId()))
                .usingJobData("taskInfoDtoJson", JSON.toJSONString(taskInfoDto))
                .build();

        CronScheduleBuilder cronScheduleBuilder = null;
        try {
            cronScheduleBuilder = CronScheduleBuilder.cronSchedule(taskInfoDto.getCron());
        } catch (Exception e) {
            LOG.error("创建trigger的cron有问题:{}", e);
        }

        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(ScheduleNameUtils.getTriggerName(this.getTaskSubId()),
                        ScheduleNameUtils.getGroupName(this.getTaskId()))
                .startNow()
                .withSchedule(cronScheduleBuilder)
                .build();

        try {
            scheduler.scheduleJob(job, trigger);
        } catch (SchedulerException e) {
            LOG.error("执行定时调度任务,job={}, trgger={},抛错:{}", job, trigger, e);
        }
        // 某种情况下,需要取消定时任务
        cancelScheduleJob(taskInfoDto.getTaskId(), taskInfoDto.getTaskSubId());
    }

    /**
     * 取消定时任务
     * 
     * @param taskId
     * @param taskSubId
     * @return
     */
    public boolean cancelScheduleJob(String taskId, String taskSubId) {
        Scheduler scheduler = null;
        scheduler = QuartzScheduleUtils.getInstanceScheduler();
        if (scheduler == null) {
            return false;
        }

        boolean isSuc = false;
        TriggerKey triggerKey = new TriggerKey(ScheduleNameUtils.getTriggerName(taskSubId),
                ScheduleNameUtils.getGroupName(taskId));
        try {
            isSuc = scheduler.unscheduleJob(triggerKey);
        } catch (SchedulerException e) {
            LOG.error("移除任务时抛错:{}", e);
        }
        return isSuc;
    }

 

posted @ 2017-07-15 10:31  乐在克里特  阅读(149)  评论(0编辑  收藏  举报