开发者社区> 问答> 正文

Quartz做定时任务,如何能达到手动控制这个任务的执行与终止?

大概业务需要是这样的:

我的系统需要和另一个系统做交互,对方系统将数据处理后会自动推送到我系统,但是可能出现推送失败的情况,这个时候,我就需要手动启动一个定时任务,每隔多少分钟请求一次(当然这个很简单),并且只去请求固定次数,如10此后就不再启动,自动取消这个定时任务。当拿到结果后,我也要停止这个定时任务。

希望大家给点思路。

展开
收起
小旋风柴进 2016-03-05 15:13:43 21663 0
1 条回答
写回答
取消 提交回答
  • 实现思路:
    1.Quartz的JobDetail可以是无状态的,也可以是有状态的。Trigger无状态的,所以只能使用JobDetail有状态的子接口StatefulJob.Job代码如下:

    package test.quartz.spring;  
      
    import java.util.Date;  
      
    import org.quartz.Job;  
    import org.quartz.JobDataMap;  
    import org.quartz.JobExecutionContext;  
    import org.quartz.JobExecutionException;  
    import org.quartz.StatefulJob;  
      
    public class TJob implements StatefulJob {  
      
        /** 
         * 不用挣扎了,Quartz都是无状态的,他不知道执行了几次。 
         * 如果想要记录状态就需要持久化到数据库. 
         */  
        public void execute(JobExecutionContext cntxt) throws JobExecutionException {  
               
            JobDataMap jobDataMap = cntxt.getJobDetail().getJobDataMap();  
            Integer count = (Integer) jobDataMap.get("count");  
            if(count==null){  
                count=0;  
            }  
            count++;  
             System.out.println("杨春龙,太帅了");  
             System.out.println("不是我说的");  
             System.out.println( " Generating report -  "  
                    +  count  
                    +  "-"  
                    +   new  Date());  
             jobDataMap.put("count", count);  
             cntxt.getJobDetail().setJobDataMap(jobDataMap);  
               
      
        }  
      
    }  

    根据ApI描述,如果是有状态的Job,所有的Job都共享jobDataMap,所有把执行次数记录下来.虽然我记录了执行次数,但是因为Job是一个Thread,由ThreadPool来维持,那么如何监视Job的执行情况,在看源码中,发现有一个Listener,可以监听进程的执行,代码如下:

    package test.quartz.spring;  
      
    import org.quartz.CronTrigger;  
    import org.quartz.JobExecutionContext;  
    import org.quartz.SchedulerException;  
    import org.quartz.Trigger;  
    import org.quartz.listeners.TriggerListenerSupport;  
      
    public class TriggerListener extends TriggerListenerSupport {  
          
        private String name;    
          
        private Integer count;   
        public void setName(String name)     
        {     
            this.name=name;     
        }     
          
        public String getName() {  
            // TODO Auto-generated method stub  
            return this.name;  
        }  
          
      
        public Integer getCount() {  
            return count;  
        }  
      
        public void setCount(Integer count) {  
            this.count = count;  
        }  
      
        @Override  
        public void triggerComplete(Trigger trigger, JobExecutionContext context,  
                int triggerInstructionCode) {  
            System.out.println("Trigger :"+trigger.getGroup()+"."+trigger.getName()+" completed with code:"+triggerInstructionCode);  
            Integer current = (Integer) context.getJobDetail().getJobDataMap().get("count");  
            System.out.println("调用次数:"+current);    
            if(current == count){  
                try {  
                    context.getScheduler().shutdown();  
                } catch (SchedulerException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
            super.triggerComplete(trigger, context, triggerInstructionCode);  
        }  
      
          
      
    }  

    在Job的执行中设置执行次数,在监听器中得到执行次数,当执行次数到达count的时候退出执行.
    JobQuartz.xml配置如下

    <?xml version="1.0" encoding="UTF-8"?>  
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">  
      
    <beans>  
    <!--要调度的对象-->  
      
        <bean id="job" class="test.quartz.spring.TJob"></bean>  
        <bean id="triggerListener" class="test.quartz.spring.TriggerListener">  
            <property name="name">  
                <value>triggerListener</value>  
            </property>  
            <property name="count">  
                <value>3</value>  
            </property>   
        </bean>  
    <!-- 定义目标bean和bean中的方法 -->  
        <bean id="jobtask" class="org.springframework.scheduling.quartz.JobDetailBean">  
            <property name="jobClass">  
                <value>test.quartz.spring.TJob</value>  
            </property>  
      
        </bean>  
    <!-- 定义触发的时间 -->  
        <bean id = "cron" class = "org.springframework.scheduling.quartz.CronTriggerBean">  
            <!-- jobDetail中的name,group都已经设置 -->  
            <property name="jobDetail">  
                <ref bean="jobtask"/>  
            </property>  
            <property name="triggerListenerNames">    
                <list>    
                   <value>triggerListener</value>    
                </list>    
            </property>     
            <property name="cronExpression">  
                <value>0/10 * * * * ?</value>  
            </property>   
        </bean>  
    <!-- 总管理 -->  
        <bean autowire = "no" class = "org.springframework.scheduling.quartz.SchedulerFactoryBean">  
            <property name="triggers">  
                <list>  
                    <ref local ="cron"/>  
                </list>  
            </property>  
            <!-- 添加监听器 -->  
            <property name="triggerListeners">    
                <list>    
                    <ref bean="triggerListener"/>   
                </list>    
            </property>    
              
        </bean>  
      
    </beans>  

    在SchedulerFactoryBean中配置监听器列表,在CronTriggerBean配置监听器名称,这样这个监听器就可以监听这个Trigger了,当执行了3次后自动退出
    测试代码如下:

    package test.quartz.spring;  
      
    import org.springframework.context.ApplicationContext;  
    import org.springframework.context.support.ClassPathXmlApplicationContext;  
      
    public class TestSpring {  
      
        /** 
         * @param args 
         */  
        public static void main(String[] args) {  
            System.out.println("测试开始");  
            ApplicationContext ctx = new ClassPathXmlApplicationContext("JobQuartz.xml");  
            System.out.println("测试结束");  
      
        }  
      
    }  

    测试输出如下:
    测试开始

    Java代码  收藏代码
    2010-09-27 09:33:39,640 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] - <Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3e86d0: display name [org.springframework.context.support.ClassPathXmlApplicationContext@3e86d0]; startup date [Mon Sep 27 09:33:39 CST 2010]; root of context hierarchy>  
    2010-09-27 09:33:39,718 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [JobQuartz.xml]>  
    2010-09-27 09:33:39,781 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] - <Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@3e86d0]: org.springframework.beans.factory.support.DefaultListableBeanFactory@197a37c>  
    2010-09-27 09:33:39,812 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@197a37c: defining beans [job,triggerListener,jobtask,cron,org.springframework.scheduling.quartz.SchedulerFactoryBean#0]; root of factory hierarchy>  
    2010-09-27 09:33:39,953 INFO [org.quartz.core.SchedulerSignalerImpl] - <Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl>  
    2010-09-27 09:33:39,953 INFO [org.quartz.core.QuartzScheduler] - <Quartz Scheduler v.1.8.3 created.>  
    2010-09-27 09:33:39,953 INFO [org.quartz.simpl.RAMJobStore] - <RAMJobStore initialized.>  
    2010-09-27 09:33:39,953 INFO [org.quartz.core.QuartzScheduler] - <Scheduler meta-data: Quartz Scheduler (v1.8.3) 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' with instanceId 'NON_CLUSTERED'  
      Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.  
      NOT STARTED.  
      Currently in standby mode.  
      Number of jobs executed: 0  
      Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.  
      Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.  
    >  
    2010-09-27 09:33:39,953 INFO [org.quartz.impl.StdSchedulerFactory] - <Quartz scheduler 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' initialized from an externally provided properties instance.>  
    2010-09-27 09:33:39,953 INFO [org.quartz.impl.StdSchedulerFactory] - <Quartz scheduler version: 1.8.3>  
    2010-09-27 09:33:39,953 INFO [org.quartz.core.QuartzScheduler] - <JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@1b09468>  
    2010-09-27 09:33:39,953 INFO [org.springframework.scheduling.quartz.SchedulerFactoryBean] - <Starting Quartz Scheduler now>  
    2010-09-27 09:33:39,953 INFO [org.quartz.core.QuartzScheduler] - <Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED started.>  
    测试结束  
    杨春龙,太帅了  
    不是我说的  
     Generating report -  1-Mon Sep 27 09:33:40 CST 2010  
    Trigger :DEFAULT.cron completed with code:0  
    调用次数:1  
    杨春龙,太帅了  
    不是我说的  
     Generating report -  2-Mon Sep 27 09:33:50 CST 2010  
    Trigger :DEFAULT.cron completed with code:0  
    调用次数:2  
    杨春龙,太帅了  
    不是我说的  
     Generating report -  3-Mon Sep 27 09:34:00 CST 2010  
    Trigger :DEFAULT.cron completed with code:0  
    调用次数:3  
    2010-09-27 09:34:00,000 INFO [org.quartz.core.QuartzScheduler] - <Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED shutting down.>  
    2010-09-27 09:34:00,000 INFO [org.quartz.core.QuartzScheduler] - <Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED paused.>  
    2010-09-27 09:34:00,000 INFO [org.quartz.core.QuartzScheduler] - <Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED shutdown complete.>  
    2019-07-17 18:53:34
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载