zoukankan      html  css  js  c++  java
  • 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;
        }
  • 相关阅读:
    [BZOJ1492][NOI2007]货币兑换Cash(斜率优化+CDQ分治)
    [P1768]天路(分数规划+SPFA判负环)
    [BZOJ5109][LOJ #6252][P4061][CodePlus 2017 11月赛]大吉大利,今晚吃鸡!(最短路+拓扑排序+传递闭包+map+bitset(hash+压位))
    [BZOJ1040][ZJOI2008]骑士(环套树dp)
    [P3759][TJOI2017]不勤劳的图书管理员(分块+树状数组)
    [CF665F]Four Divisors
    [LOJ6235]区间素数个数
    [SDOI2015]约数个数和
    [BZOJ3944]Sum
    [BZOJ2671]Calc
  • 原文地址:https://www.cnblogs.com/itommy/p/10610317.html
Copyright © 2011-2022 走看看