我有一个Java程序,每20秒从Spring Qquartz执行一次。有时执行只需几秒钟,但随着数据变大,我确信它会运行20秒或更长时间。
如何在一个实例仍在执行时阻止Quartz触发/触发作业?在数据库上执行2个执行相同操作的作业并不是那么好。有没有办法可以进行某种同步?
答案 0 :(得分:133)
如果您更改类以实现StatefulJob而不是Job,Quartz将为您处理此问题。来自StatefulJob javadoc:
不允许有状态的工作 并发执行,这意味着新的 在之前发生的触发器 完成execute(xx)方法 将被推迟。
StatefulJob扩展了Job并且没有添加任何新方法,所以你需要做的就是改变它:
public class YourJob implements org.quartz.Job {
void execute(JobExecutionContext context) {/*implementation omitted*/}
}
对此:
public class YourJob implements org.quartz.StatefulJob {
void execute(JobExecutionContext context) {/*implementation omitted*/}
}
在Quartz 2.0版中,不推荐使用StatefulJob
。现在建议使用注释,例如
@DisallowConcurrentExecution
public class YourJob implements org.quartz.Job {
void execute(JobExecutionContext context) {/*implementation omitted*/}
}
答案 1 :(得分:31)
如果你需要做的就是每20秒开火一次,石英就会严重过度杀伤。 java.util.concurrent.ScheduledExecutorService
应该足以完成这项工作。
ScheduledExecutorService
还为调度提供了两种语义。 "fixed rate"将尝试每20秒运行一次作业而不管重叠,而"fixed delay"将尝试在第一个作业结束和下一个作业开始之间留出20秒。如果你想避免重叠,那么固定延迟是最安全的。
答案 2 :(得分:18)
如果有人引用此问题,则StatefulJob已被弃用。他们现在建议你使用注释......
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class TestJob implements Job {
这将解释这些注释的意思......
注释会导致行为 他们的名字描述 - 多个 工作的实例不会 允许同时运行(考虑 作业中包含代码的情况 execute()方法需要34秒 运行,但它安排了一个 触发器每30次重复一次 秒),并将拥有其JobDataMap 内容重新保留在 调度程序的JobStore在每个之后 执行。出于此目的 仅举例说明 @PersistJobDataAfterExecution 注释是真正相关的,但它是 总是明智地使用 @DisallowConcurrentExecution 用它来注释,以防止 保存数据的竞争条件。
答案 3 :(得分:4)
如果你使用弹簧石英,我认为你必须像这样配置
<bean id="batchConsumerJob"class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="myScheduler" />
<property name="targetMethod" value="execute" />
<property name="concurrent" value="false" />
</bean>
答案 4 :(得分:2)
我不确定你是否想要同步,因为第二个任务将阻塞直到第一个完成,你最终会得到一个积压。您可以将作业放入队列中,但从您的描述中可以看出队列可能会无限增长。
我会调查ReadWriteLock,让你的任务在运行时设置锁定。未来的任务可以检查此锁定,并在旧任务仍在运行时立即退出。我从经验中发现,这是解决这个问题最可靠的方法。
也许还会生成警告,因此您知道自己遇到问题并相应地增加时间间隔?
答案 5 :(得分:0)
将它们放入队列
即使时间超过20秒,也应该完成当前的工作。那么下一个应该从队列中获取。
或者您也可以将时间增加到合理的数量。
答案 6 :(得分:0)
您可以使用信号量。当信号量被拿走时,放弃第二个工作并等到下一个火灾时间。