Starting with the thread, let's look at the Quartzschedulerthread class (responsible for performing the work of the triggering trigger):
@Override public
Void Run () {
Boolean lastacquirefailed = false;
while (!halted.get ()) {
try {
//check if we ' re supposed to pause
... Synchronized (Siglock) {while
(paused &&!halted.get ()) {
try {
//wait until Togglepause (false) is C
alled ... Siglock.wait (1000L);
} catch (Interruptedexception ignore) {
}
}
if (Halted.get ()) {break
;
}
}
int availthreadcount = Qsrsrcs.getthreadpool (). Blockforavailablethreads ();
The Atomicboolean class Halted.get () is used to check whether the trigger is paused, the previous version of the Quartz is a Boolean, and the Atomicboolean class is not updated until the value is stable, keeping the atomic nature of the operation. As you can see from the code above, thread will wait until the trigger stops or waits. The Siglock synchronization object is used to wake up the trigger that will be triggered (using Notifyall to wake the wait thread, the following source)
Synchronized (siglock) {
signaled = true;
Signalednextfiretime = Candidatenewnextfiretime;
Siglock.notifyall ();
}
Qsrsrcs.getthreadpool (). Blockforavailablethreads ()//Get thread pool can now use the number of threads
Configurations integrated with spring (recommended for general use 10~50 threads): The following line of code configures the maximum number of threads
<prop key= "Org.quartz.threadPool.threadCount" >40</prop>
Connect the Run method code above:
if (Availthreadcount > 0) {//'ll always is true, due to semantics of blockforavailablethreads ...
List<operabletrigger> triggers = null;
Long now = System.currenttimemillis ();
Clearsignaledschedulingchange ();
try {//Find a certain number of trigger triggers = Qsrsrcs.getjobstore () in 30 seconds. Acquirenexttriggers ( Now + Idlewaittime, Math.min (Availthreadcount, Qsrsrcs.getmaxbatchsize ()), Qsrsrcs.getbatchtimewi
Ndow ());
lastacquirefailed = false;
...
} ... if (triggers!= null &&!triggers.isempty ()) {now = Syste
M.currenttimemillis ();
Long triggertime = triggers.get (0). Getnextfiretime (). GetTime ();
Long Timeuntiltrigger = Triggertime-now; while (Timeuntiltrigger > 2) {synchronized (Siglock) {
if (Halted.get ()) {break;
} if (!iscandidatenewtimeearlierwithinreason (Triggertime, false)) {
try {//We could have blocked a long while On ' Synchronize ', so we must recompute now = System.currenttime
Millis ();
Timeuntiltrigger = Triggertime-now;
if (Timeuntiltrigger >= 1) siglock.wait (Timeuntiltrigger);
catch (Interruptedexception ignore) {}
}
... Boolean goahead = true;
Synchronized (siglock) {goahead =!halted.get (); } if (Goahead) {try {List<triggerf
iredresult> res = Qsrsrcs.getjobstore (). triggersfired (triggers);
if (res!= null) Bndles = res;
}
...
}
for (int i = 0; i < bndles.size (); i++) {... if (Bndle = = null) {Qsrsrcs.getjobstore (). Releaseacq
Uiredtrigger (Triggers.get (i));
Continue }
Availthreadcount must be greater than 0, because there must be at least one thread to handle trigger.
The above code basically does is to poll (the server starts and executes the Run method continuously):
Qsrsrcs.getjobstore (). Acquirenexttriggers "Find the trigger that will be triggered"---->
Siglock.wait (Timeuntiltrigger) "Waiting for execution"---->
Qsrsrcs.getjobstore (). triggersfired (triggers) "executive"---->
Qsrsrcs.getjobstore (). Releaseacquiredtrigger (Triggers.get (i)) "release of Trigger"