• 动态改变Quartz的调度时间


    最近几天项目里的定时器常常发生异常,比如:

    1、修改linux系统时间时,定时任务全挂掉不动了。

    2、在页面里面动态修改任务时间,常常不执行了。

    下面是一些网友的资料,暂时收集放着,有时间将去验证和修改自己系统的问题。



    近日碰到一位友人提出的一个问题,如何动态的改变Quartz的调度作业的时间。比如,由每10分钟执行一次改为每5分钟执行一次。个人认为这种需求应该 通过某种方式来规避,或者选用其他的技术框架,因为动态改变Quartz的调度时间完全失去了使用Quartz的意义。本人在使用Quartz是基于 Spring来配置的,而朋友的项目中不能使用SPring框架,这就需要直接基于Quartz编程。工作之余,写了个例子:
    Quartz的管理类

    Java代码  收藏代码
    1. public   class  QuartzManage {  
    2.     private   static  SchedulerFactory sf =  new  StdSchedulerFactory();  
    3.     private   static  String JOB_GROUP_NAME =  "group" ;  
    4.     private   static  String TRIGGER_GROUP_NAME =  "trigger" ;  
    5.   
    6.     public   static   void  startJob(String jobName, Job job, String time)  
    7.             throws  SchedulerException, ParseException {  
    8.         Scheduler sched = sf.getScheduler();  
    9.   
    10.         JobDetail jobDetail = new  JobDetail();  
    11.         jobDetail.setName(jobName);  
    12.         jobDetail.setGroup(JOB_GROUP_NAME);  
    13.         jobDetail.setJobClass(job.getClass());  
    14.   
    15.         CronTrigger trigger = new  CronTrigger(jobName, TRIGGER_GROUP_NAME);  
    16.         trigger.setCronExpression(time);  
    17.         sched.scheduleJob(jobDetail, trigger);  
    18.   
    19.         if  (!sched.isShutdown()) {  
    20.             sched.start();  
    21.         }  
    22.     }  
    23.   
    24.     /**  
    25.      * 从Scheduler 移除当前的Job,修改Trigger  
    26.      *   
    27.      * @param jobDetail  
    28.      * @param time  
    29.      * @throws SchedulerException  
    30.      * @throws ParseException  
    31.      */   
    32.     public   static   void  modifyJobTime(JobDetail jobDetail, String time)  
    33.             throws  SchedulerException, ParseException {  
    34.         Scheduler sched = sf.getScheduler();  
    35.         Trigger trigger = sched.getTrigger(jobDetail.getName(),  
    36.                 TRIGGER_GROUP_NAME);  
    37.         if  (trigger !=  null ) {  
    38.             CronTrigger ct = (CronTrigger) trigger;  
    39.             // 移除当前进程的Job   
    40.             sched.deleteJob(jobDetail.getName(), jobDetail.getGroup());  
    41.             // 修改Trigger   
    42.             ct.setCronExpression(time);  
    43.             System.out.println("CronTrigger getName "  + ct.getJobName());  
    44.             // 重新调度jobDetail   
    45.             sched.scheduleJob(jobDetail, ct);  
    46.         }  
    47.     }  
    48.   
    49. }  


    Job任务:

    Java代码  收藏代码
    1. public   class  JobTest  implements  Job {  
    2.     static   int  a =  0 ;  
    3.   
    4.     @Override   
    5.     public   void  execute(JobExecutionContext context)  
    6.             throws  JobExecutionException {  
    7.         a += 1 ;  
    8.         System.out.println("test ++++++++++++++++++++++a="  + a);  
    9.   
    10.         if  (a ==  4 ) {  
    11.             try  {  
    12.                 QuartzManage.modifyJobTime(context.getJobDetail(),  
    13.                         "0/10 * * * * ?" );  
    14.             } catch  (SchedulerException e) {  
    15.                 e.printStackTrace();  
    16.             } catch  (ParseException e) {  
    17.                 e.printStackTrace();  
    18.             }  
    19.         }  
    20.     }  
    21.   
    22. }  


    启动线程执行调度:

    Java代码  收藏代码
    1. public   class  QuartzTest {  
    2.     public   static   void  main(String[] args)  throws  SchedulerException,  
    3.             ParseException {  
    4.         /*  
    5.          * 此进程为主进程,触发了quartz对Job的调度 因此启动Job之后,在该进程修改调度,是没有效果的  
    6.          */   
    7.         JobTest job = new  JobTest();  
    8.         QuartzManage.startJob("ming" , job,  "0/2 * * * * ?" );  
    9.     }  
    10. }  



    好多人的思路是在启动的主线程内去改变调度的时间,简单的分析就可发现,主线程启动之后就会按照调度时间去运行Job,不会返回主线程再去加载调度时间,只是起到了触发调度的操作。因此要进行动态的修改调度时间,需要在Job任务里,动态改变当前线程的调度计划。

    测试代码,开始时按每2秒执行一次打印a,当a打印4次以后,按照每10秒一次执行。虽然代码测试成功,本人还有疑惑。

    Java代码  收藏代码
    1. // 移除当前进程的Job   
    2.             sched.deleteJob(jobDetail.getName(), jobDetail.getGroup());  


    先移除当前的Job任务,在按照新的调度时间加入新的Job,虽然可以实现动态的改变,不知道是否带来了其他的问题。
    欢迎大家批评指正共同测试、验证!

  • 相关阅读:
    iphone/iOS 访问本地数据库sqlite3
    SQLITE3 --详解
    iOS使用MD5
    ASIHTTPRequest实现断点续传
    ios开发
    iOS 5的文件存储策略应对
    由ASIHttpRequest里的block引发的思考
    Blocks编程要点
    [Cocoa]深入浅出Cocoa多线程编程之 block 与 dispatch quene
    ASIHTTPRequest 问题总结
  • 原文地址:https://www.cnblogs.com/cuker919/p/4878566.html
Copyright © 2020-2023  润新知