答案 0 :(得分:2)
我听起来你正在遇到一个失误的场景(这个场景中有更多的工作准备好执行而不是工作线程)。在触发器上设置misfire指令和/或优先级属性,以更改每个触发器超过其触发时间后的行为。
此外,您可以考虑增加失火阈值,这会改变触发器在被认为失火之前等待线程执行的“迟到”的时间(并且应用了失火指令)
一旦Quartz ThreadPool中的空间可用,是否有可能使我的等待(失火)作业按照它们被触发的顺序被触发?
“不执行任何操作”说明将按原样保留开火时间。
答案 1 :(得分:2)
当石英处理一个错过了它的开火时间的触发器时,它会更新触发器的nextFireTime
。默认情况下,如果过去的nextFireTime超过60秒,则会认为触发器被丢失。仍应根据nextFireTime和优先顺序选择错过的触发器,但我猜它似乎是随机的,因为某些触发器已更新而其他触发器未更新。
我建议增加org.quartz.jobStore.misfireThreshold
属性。请参阅http://www.quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigRAMJobStore.html(尽管所有JobStore的属性都相同)。这样可以减少重新安排触发器的可能性。
答案 2 :(得分:0)
查看quartz thread pool ,它使用了wait()/ notify()循环,这是不公平的,并且会在多个线程等待时随机选择一个新线程。
您可以使用自己的ThreadPool实例,这是公平的。从SimpleThreadPool复制代码,但将nextRunnableLock周围的锁定替换为java.util.ReentrantLock,将true传递给fair构造函数。在您修改的SimpleThreadPool中,使用ReentrantLock.lock()/ unlock()而不是synchronized,并使用ReentrantLock.newCondition()。signal()/ await()而不是wait / notify,它可能会解决您的问题。
答案 3 :(得分:0)
如果是CronTrigger
,方法updateAfterMisfire()
可能会在new Date()
案例MISFIRE_INSTRUCTION_FIRE_ONCE_NOW
政策中重新安排任务。
如果多个任务失灵,可能会同时重新安排其中几个任务(相同的毫秒),因为计算机运行速度很快。
因此,如果没有定义优先级,调度程序将根据密钥或全名提取第一个具有相同NextFireTime
的下一个任务。
updateAfterMisfire()
方法应该使用date
将任务重新安排为唯一的Thread.sleep(25)
,作为示例。