动态改变Quartz的调度时间

本文介绍了一种在Quartz中动态更改任务调度时间的方法,包括通过删除旧的任务并创建新的任务来实现时间的更新,并提供了一个示例,说明如何在任务执行过程中调整其自身的调度间隔。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

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



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

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


Job任务:

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


启动线程执行调度:

Java代码 收藏代码
  1. public class QuartzTest{
  2. public static void main(String[]args) throws SchedulerException,
  3. ParseException{
  4. /*
  5. *此进程为主进程,触发了quartz对Job的调度因此启动Job之后,在该进程修改调度,是没有效果的
  6. */
  7. JobTestjob=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,虽然可以实现动态的改变,不知道是否带来了其他的问题。
欢迎大家批评指正共同测试、验证!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值