Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我能按触发的顺序让它们开火吗?_Java_Quartz Scheduler - Fatal编程技术网

Java 我能按触发的顺序让它们开火吗?

Java 我能按触发的顺序让它们开火吗?,java,quartz-scheduler,Java,Quartz Scheduler,我有一个使用Quartz调度程序来调度作业的应用程序。该应用程序当前正在运行Quartz版本1.6.2。我的JobStore是org.quartz.impl.jdbcjobstore.JobStoreTX,有一个Oracle数据库支持。集群已打开,但只有一个调度程序使用数据库。我的石英线程池配置如下: org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount

我有一个使用Quartz调度程序来调度作业的应用程序。该应用程序当前正在运行Quartz版本1.6.2。我的JobStore是org.quartz.impl.jdbcjobstore.JobStoreTX,有一个Oracle数据库支持。集群已打开,但只有一个调度程序使用数据库。我的石英线程池配置如下:

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 5
我的作业是长时间运行的,所以当触发器触发新作业时,运行5个作业(thead池允许的最大值)是相当常见的。新触发的作业不点火,我看到如下日志消息:

2011-05-20 04:09:30,097 INFO  [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT  at:  04:09:30 05/20/2011.  Should have fired at:  04:08:29 05/20/2011
2011-05-20 04:09:30,120 INFO  [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT  at:  04:09:30 05/20/2011.  Should have fired at:  04:09:30 05/20/2011
2011-05-20 04:09:30,125 INFO  [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT  at:  04:09:30 05/20/2011.  Should have fired at:  04:08:30 05/20/2011
2011-05-20 04:09:30,138 INFO  [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT  at:  04:09:30 05/20/2011.  Should have fired at:  04:09:30 05/20/2011
2011-05-20 04:11:29,998 INFO  [QuartzScheduler_scheduler-servername-111305822376676_MisfireHandler] o.q.impl.jdbcjobstore.JobStoreTX - Handling 2 trigger(s) that missed their scheduled fire-time.
一旦运行的作业完成,其中一个缺火的作业将被拾取并正常运行。然而,Quartz似乎随机选择了一个失败的作业,而不考虑作业最初计划执行的顺序。理想情况下,我希望根据它们最初的开火时间,按照它们应该运行的顺序来拾取它们

当Quartz线程池中的空间可用时,是否可以按触发顺序触发我的等待(失败)作业?

查看Quartz,它使用wait()/notify()循环,这是不公平的,并且在多个线程等待时会随机选择一个新线程


您可以使用自己的ThreadPool实例,这是公平的。从SimpleThreadPool复制代码,但将nextRunnableLock周围的锁定替换为java.util.ReentrantLock,并将true传递给fair构造函数。在修改后的SimpleThreadPool中,使用ReentrantLock.lock()/unlock()而不是synchronized,使用ReentrantLock.newCondition().signal()/wait()而不是wait/notify,这可能会解决您的问题。

听起来您遇到了失火的情况(准备执行的作业比工作线程多的场景)。设置触发器上的“缺火指令”和/或“优先级”属性,以更改每个触发器在超过其启动时间后的行为方式

此外,您可以考虑增加失火阈值,这将改变触发器在被认为失火之前“等待”一个线程执行的时间量(并对其应用了失火指令)。 当Quartz线程池中的空间可用时,是否可以按触发顺序触发我的等待(失败)作业


“什么也不做”指令将保持点火时间不变。

如果发生
CronTrigger
,则方法
updateAfterMisfire()
可以在
新日期()重新安排任务。
案例
失火指令\u立即点火一次
策略

如果多个任务失败,其中几个任务可能会在同一时间(相同毫秒)重新调度,因为计算机运行速度很快

因此,如果没有定义优先级,调度程序将根据键或全名选择下一个任务,所有任务都具有相同的
NextFireTime


updateAfterMisfire()
方法应该使用
线程将任务重新安排到唯一的
日期
,例如。

当quartz处理错过触发时间的触发器时,它将更新触发器的
nextFireTime
。默认情况下,如果触发器的nextFireTime在过去超过60秒,则将被视为错过。错过的触发器仍应根据nextFireTime和优先级顺序选择,但我猜是这样的它看起来是随机的,因为一些触发器已经更新,而另一些则没有


我建议增加
org.quartz.jobStore.misfirestreshold
属性。请参阅(尽管所有jobStore的属性都相同)。这将减少重新调度触发器的可能性。

池中的线程没有分配作业,因此您所说的公平性无关紧要。这些线程中的任何一个先释放出来,都将运行下一个作业。我认为公平性来自线程池外的线程runInThread和blockForAvailableThreads和blockForAvailableThreads()都是从同一个线程调用的,没有多个线程在等待这些方法的结果,所以wait()/notify()的“公平性”无关紧要。(只有一个线程服务/使用线程池)。为了提供更多信息,我对这个问题进行了一些编辑。通过“我的线程池已用完”我的意思是Quartz线程池没有工作线程来运行作业,导致新触发的作业无法启动。这肯定是一个无法启动的场景-我已经更新了问题,使其更具体一点。是否有一个无法启动的指令可以使无法启动的作业按照最初启动的顺序启动?MISFIRE_指令\u DO_NOTHING MISFIRE的javadoc如下所示:“指示调度程序在发生误触发情况时,CronTrigger希望将其下一次触发时间更新到计划中当前时间之后的下一次,但不希望现在触发。”也许我误解了,但这听起来像是作业会跳过触发,在下次触发之前什么也不做。这不是我想要的。我希望作业在有可用线程时立即运行,但如果有多个失败的作业,等待时间最长的作业会先运行。我无法真正测试这一点,因为我有一份新的工作,多年没有使用石英,也不想费心去建立一个测试项目,只是为了看看这是否有效。然而,我印象深刻的是,你费心去回答一个5年前的问题,而你的答案似乎很有帮助,所以我将继续,并将此标记为已解决:)我遇到了一个类似的问题,搜索堆栈溢出也是如此。最后我翻遍了代码,找到了自己的答案,但我想我会把这个留在这里,以防将来有人在搜索答案