首页 > 解决方案 > 停止使用 MethodInvokingJobDetailFactoryBean 创建的 Quartz 作业

问题描述

我用这段代码创建了一个运行 Spring bean 类的作业



  MethodInvokingJobDetailFactoryBeanjobDetail = new MethodInvokingJobDetailFactoryBean();
        Class<?> businessClass = Class.forName(task.getBusinessClassType());
        jobDetail.setTargetObject(applicationContext.getBean(businessClass));
        jobDetail.setTargetMethod(task.getBusinessMethod());
        jobDetail.setName(task.getCode());
        jobDetail.setGroup(task.getGroup().getCode());
        jobDetail.setConcurrent(false);

        Object[] argumentArray = builArgumentArray(task.getBusinessMethodParams());
        jobDetail.setArguments(argumentArray);

        jobDetail.afterPropertiesSet();

        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getCode() + "_TRIGGER", task.getGroup().getCode() + "_TRIGGER_GROUP")
                      .withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression())).build();

        dataSchedulazione = scheduler.scheduleJob((JobDetail) jobDetail.getObject(), trigger);
        scheduler.start();

如果我删除触发器并且调度程序中的任务保留在中,有时任务停止响应
List ob = scheduler.getCurrentlyExecutingJobs();

触发器的状态为 NONE 但仍在 scheduler.getCurrentlyExecutingJobs();

我试图在扩展 MethodInvokingJobDetailFactoryBeanjobDetail 的类中实现 InterruptableJob

但是当我使用

scheduler.interrupt(jobKey);

它说 InterruptableJob 没有实现。我认为是因为该类的实例是 MethodInvokingJobDetailFactoryBeanjobDetail

`scheduler.scheduleJob((JobDetail) jobDetail.getObject(), trigger);`

这是石英调度程序中的代码

`job = jec.getJobInstance();
                if (job instanceof InterruptableJob) {
                    ((InterruptableJob)job).interrupt();
                    interrupted = true;
                } else {
                    throw new UnableToInterruptJobException(
                            "Job " + jobDetail.getKey() +
                            " can not be interrupted, since it does not implement " +                        
                            InterruptableJob.class.getName());
                }
`

还有另一种方法可以杀死单个任务吗?

我使用 Quartz 2.1.7 和 java 1.6 和 java 1.8

TIA

安德烈亚

标签: javaspringquartz

解决方案


没有什么神奇的方法可以强制 JVM 停止执行某些代码。

您可以实施不同的方式来中断工作。但最合适的方式是实现InterruptableJob

实现这个接口是不够的。您应该以真正对此类请求做出反应的方式实施作业。

例子

假设您的工作是处理数据库或文件中的 1 000 000 条记录,这需要相对较长的时间,比如说 1 小时。然后可以遵循一种可能的实现。在方法“interrupt()”中,您将一些标志(成员变量)设置为“true”,将其命名为isInterruptionRequested。在处理 1 000 000 条记录的主要逻辑部分中,您可以定期(例如每 5 秒或每 100 条记录后)检查此标志isInterruptionRequested是否设置为“true”。如果设置,则退出实现主逻辑的方法。

不要太频繁地检查病情,这一点很重要。否则,根据逻辑,检查是否请求作业中断可能会占用 80-90% 的 CPU,比实际逻辑要多得多:)

因此,即使您正确实现了InterruptableJob接口,也不意味着作业会立即停止。这只是一个提示,例如“我想在可能的情况下停止这项工作”。何时停止(如果有的话)取决于您如何实现它。


推荐阅读