Annotation method:
Core Class Summary:
1.ScheduledAnnotationBeanPostProcessor
2.ScheduledTaskRegistrar
3.TaskScheduler
4.ReschedulingRunnable
Specific Description:
1.ScheduledAnnotationBeanPostProcessor
(1) Core method: Object Postprocessafterinitialization (Final object bean, String beanname)
Function: Responsible for scanning @schedule annotations, build ScheduleTask
(2) Core method: Onapplicationevent (Contextrefreshedevent event)
Function: After the spring container is loaded, ScheduleTask is registered to Scheduledtaskregistrar, calling Scheduledtaskregistrar.afterpropertiesset ()
2.ScheduledTaskRegistrar
(1) Core method: void Afterpropertiesset ()
Function: Initialize all timers, start timer
3.TaskScheduler
The main implementation class has three Threadpooltaskscheduler, Concurrenttaskscheduler,timermanagertaskscheduler
Role: The role of these classes is primarily to wrap tasks and executor with reschedulingrunnable for lifecycle management.
(1) Core method: Scheduledfuture Schedule (Runnable task, Trigger Trigger)
4.ReschedulingRunnable
(1) Core method: Public scheduledfuture Schedule ()
(2) Core method: public void Run ()
Public scheduledfuture Schedule () {synchronized (this.triggercontextmonitor) {This.schedule Dexecutiontime = This.trigger.nextExecutionTime (This.triggercontext); if (this.scheduledexecutiontime = = null) {return null; } Long InitialDelay = This.scheduledExecutionTime.getTime ()-System.currenttimemillis (); This.currentfuture = This.executor.schedule (this, initialdelay, timeunit.milliseconds); return this; }} @Override public void Run () {Date actualexecutiontime = new Date (); Super.run (); Date Completiontime = new Date (); Synchronized (this.triggercontextmonitor) {this.triggerContext.update (This.scheduledexecutiontime, ACTUALEXECU Tiontime, Completiontime); } if (!this.currentfuture.iscancelled ()) {schedule (); } }
Through the schedule method and the Run method call each other, and then use the Scheduledexecutorservice interface schedule (Runnable command,long delay,timeunit Unit) Single execution effect, The result is a repetition of the triggering effect for a certain time.
The configuration file is basically similar to the only way to assemble the corresponding timed task bean through the Scheduledtasksbeandefinitionparser class read node
Implementation of Spring Timer
Scheduledthreadpoolexecutor class
Public scheduledfuture<?> Schedule (Runnable command, long delay, timeunit unit) {if (Command = = null | | Unit = = null) throw new NullPointerException (); runnablescheduledfuture<?> t = decoratetask (command, New scheduledfuturetask<void> (command, NULL, Triggertime (delay, unit)); Delayedexecute (t);//delay execution of return t; }//Execute to Delaydexecute method private void Delayedexecute (runnablescheduledfuture<?> Task) {if (IsShutDown ()) Reject (Task); else {super.getqueue (). Add (Task);//Add the task to the execution queue if (IsShutDown () &&!canr Unincurrentrunstate (Task.isperiodic ()) && Remove (Task)) Task.cancel (false); else Ensureprestart ();//Call}}
if the task is not canceled
The task is not canceled, call Ensureprestart (), the Ensureprestart method calls the Addworker () method, the Addworker () method creates the Woker that performs the task, and calls the Woker Run method, Call the Runworker method
final void Runworker (Worker w) {Thread wt = Thread.CurrentThread (); Runnable task = W.firsttask; W.firsttask = null; W.unlock (); Allow interrupts Boolean completedabruptly = true; try {while (task! = NULL | | (Task = Gettask ()) = null) {W.lock (); If pool is stopping, ensure thread is interrupted; If not, the ensure thread is not interrupted. This//requires a recheck in second case to deal with//Shutdownnow race while clearing interrupt if (Runstateatleast (Ctl.get (), STOP) | | (thread.interrupted () && runstateatleast (Ctl.get (), STOP))) &&!wt.isinterrupted ()) wt.interrupt (); try {beforeexecute (WT, Task); Throwable thrown = null; try {task.run (); } catch (RuntimeException x) {thrown = x; throw x; } catch (Error x) {thrown = x; throw x; } catch (Throwable x) {thrown = x; throw new Error (x); } finally {AfterExecute (task, thrown); }} finally {task = null; w.completedtasks++; W.unlock (); }} completedabruptly = false; } finally {Processworkerexit (w, completedabruptly); }}
The tasks in the
Runworker method are obtained by calling the Gettask method in the Threadpoolexecutor class
Gettask () The scheduledthreadpoolexecutor inner class Delayedworkqueue override the Take method or the poll method is called in the method
Public runnablescheduledfuture<?> take () throws Interruptedexception {final Reentrantlock lock = This.lock; Lock.lockinterruptibly (); try {//Implement deferred execution, wait until execution time according to delay time to return runnablescheduledfuture for (;;) {runnablescheduledfuture<?> first = queue[0]; if (first = = null) available.await (); else {Long delay = First.getdelay (nanoseconds); if (delay <= 0) return Finishpoll (first); first = null; Don ' t retain ref while waiting if (leader! = NULL) available.await (); else {Thread thisthread = Thread.CurrentThread (); leader = Thisthread; try {Available.awaitnanos (delay); } finally {if (leadER = = thisthread) leader = null; }}}}} finally {if (leader = = null && queue[0] ! = null) available.signal (); Lock.unlock (); } }
Spring Timer Schedule Implementation