Quartz @DisallowConcurrentExecution允许运行类的多个实例而不是作业?

时间:2012-06-27 09:42:27

标签: java spring quartz-scheduler

我一直在研究一个调度程序引擎,它从数据库中读取调度作业并调度它们工作正常,但数据库中的行只是某些类型作业的“配置”,例如:

获取FTP的某些配置

host: imagineryHost1.com 
post: 22

和另一个同类有

host: imagineryHost2.com
post: 21

我们使用自己的触发器和自己独立的数据创建两个FPTjob。

/**
BaseJob is an Abstract class extending QuartzJobBean used to handle our logging and 
other requirements that need across all our jobs.
*/
public class FTPJob extends BaseJob {

    /**
        Called from executeInternal of QuartzJobBean 
    */
    @Override
    public boolean execute1V(JobExecutionContext context) {
        //Code to get Files from FTP.
    }
}

使用带有cron的TriggerBuilder安排这些。

如果我添加@DisallowConcurrentExecution将只允许我的FTPJob的任何一个实例在任何时间运行,但是我需要能够运行多个FTPJob实例但是将其限制为该特定配置的一个实例类。

任何有关如何进步的线索都将受到高度赞赏:)

更新

根据ftom2的回答,我去挖掘并找到了TriggerListener,因为每个作业配置都有自己的唯一ID,我可以通过运行“Veto”来完成工作。

public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
    try {
        Iterator<JobExecutionContext> it =     
        context.getScheduler().getCurrentlyExecutingJobs().iterator();

        boolean found = false;
        while(it.hasNext()) {
            JobExecutionContext job = it.next();

            if(trigger.getJobKey().equals(job.getJobDetail().getKey())) {
                return false;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

还有其他方法可以用来处理这个吗?

3 个答案:

答案 0 :(得分:1)

我不确定是否可能,但这可能是一个方向。

您可以实施JobListener,然后执行以下操作:

  1. 使用jobWasExecuted,您将在jobDetails中设置此作业完成的标志。
  2. 使用jobToBeExecuted,您将在启动之前检查作业状态并查看它是否处于运行状态,如果是 - 停止它(请参阅here),如果不是 - 让它运行并将其状态设置为运行。
  3. 希望这会有所帮助。

答案 1 :(得分:0)

很抱歉迟到了一年......但建议使用TriggerLinstener不是非线程安全的吗?在我看来,两个工作可以通过否决阶段,然后getCurrentlyExecutingJobs()返回任何工作。在同样的情况下,我在调度程序上使用了一个执行锁,它甚至更少“内置”......(想法是 - 尝试在触发器linstener中获取锁定,如果不能,则否决,从作业侦听器jobWasExecuted返回锁定)。

答案 2 :(得分:0)

看起来不允许同时执行有状态作业,您可以简单地实现StatefulJob而不是Job接口