每个Trigger对应一个job和scheduler实例instanceId,instanceId用于区分集群环境中区分各个节点
在插入Trigger和job时,会先锁定,再检查是否存在,然后再加入,防止并发插入
主要的方法QuartzSchedulerThread的run方法
1.等待调度启动
2.获得执行时间小于当前时间,且状态为STATE_WAITING的trigger(如果没有,则一直循环等待JobStoreSupport.acquireNextTrigger,这里还检查了misfired的时间,选中以后通过乐观锁防止群集并发获得,传入状态STATE_WAITING更新为STATE_ACQUIRED,如果更新数量为0,则放弃这个trigger,继续取下一条
3.triggerFired,状态变为STATE_EXECUTING(STATE_BLOCKED,STATE_PAUSED_BLOCKED,STATE_COMPLETE)
3.如果triggerFired返回null,releaseAcquiredTrigger状态变为STATE_WAITING
3.runInThread执行job
4.triggeredJobComplete状态变为STATE_WAITING(STATE_PAUSED,STATE_COMPLETE,STATE_ERROR)
每个QuartzSchedulerThread都是一个带标志的死循环
如果是statefulJob,在前一次的job没有执行完或者耗费了很长时间才执行完,后几次的trigger时间都小于当前时间,所以acquireNextTrigger必定会查到这个trigger,被延迟的trigger将被顺序的连续触发,中间无间隔。因为同一个trigger同一时间的触发只有一条记录,不会出现并发的。