Article Contents:
Overview and working principles of scheduled tasks
Scheduled tasks based on annotations (@scheduled)
Scheduled tasks based on the interface SchedulingConfigurer
A scheduled task whose time can be changed
I. Overview and principle of scheduled task
Overview: Scheduled tasks are often used in development, and as the name implies, a scheduled task is a method of scheduled execution, i.e., code that is scheduled to execute. To reduce the burden on the server or database, for example, we will put some on A server or database, such as high frequency operation pressure, timing to perform instead, such as every night at 0 am synchronization system, A system of data to B statistical user integral situation, every 2 hours A week to pay treasure to users to push revenue expenditure data report last week, etc. Generally, a lot of services are processed in the early hours of the morning, because the peak user usage is avoided, the server resources are sufficient, and the impact on users is small.
Principle: the spring after the initialization bean, through “postProcessAfterInitialization” intercepted all use “@ Scheduled” annotation methods, annotations and parses the corresponding parameters, in the “timing task list” wait for subsequent processing; Then perform scheduled tasks in Scheduled Task List. The scheduled tasks are executed in sequence. Cron is executed first, and fixedRate is executed later.
Scheduled tasks based on annotations (@scheduled
Note that @Scheduled is serial, single-threaded by default, and when multiple tasks are started, the execution time of the task will be affected by the execution time of the previous task.
@Configuration
@enablescheduling // Enable a scheduled task
public class ScheduleTask {
// This command is executed every 10 seconds
@Scheduled(cron = “0/10 * * * * ?” )
private void configureTasks() {
System.out.println(” I am a timed task “);
}
}
@scheduled Provides three additional methods in addition to cron: fixedRate, fixedDelay, and initialDelay
1. Cron expressions can be customized to execute tasks, but in a manner similar to fixedDelay, counting from the end time of the last method.
2. FixedDelay specifies the interval between the execution of a fixedDelay control method. If the last execution of a fixedDelay is blocked, the next execution of a fixedDelay control method will be executed after the last execution of a fixedDelay control method.
@Configuration
@enablescheduling // Enable a scheduled task
public class ScheduleTask {
// This command is executed every 10 seconds
@Scheduled(fixedDelay = 10000)
private void configureTasks() {
System.out.println(” I am a timed task “);
}
}
3, fixedRate is according to the rate at which a certain implementation, from the starting time of the last method execution, if the last block up the method, the next is not executed, but in the blocked during this period the number of total should be performed, when no longer block, these all at once to perform, then according to the fixed rate to continue.
@Configuration
@enablescheduling // Enable a scheduled task
public class ScheduleTask {
// This command is executed every 10 seconds
@Scheduled(fixedRate = 10000)
private void configureTasks() {
System.out.println(” I am a timed task “);
}
}
4. InitialDelay = 10000 indicates that the timer should be executed again after 10 seconds after the container is started.
@Configuration
@enablescheduling // Enable a scheduled task
public class ScheduleTask {
// After the container is started, the timer will be executed again after 10 seconds. After that, the timer will be executed every 10 seconds.
@Scheduled(initialDelay = 10000, fixedRate = 10000)
private void configureTasks() {
System.out.println(” I am a timed task “);
}
}
SchedulingConfigurer based scheduled tasks
Some programmers may find it convenient to use the @Scheduled annotation, but the downside is that when we change the execution cycle, we need to restart the application to take effect, which is somewhat inconvenient. To achieve real-time effectiveness, you can use interfaces to complete scheduled tasks.
The following example fetches the execution cycle time from the data and dynamically executes the scheduled task:
@Configuration
@enablescheduling // Enable a scheduled task
public class DynamicScheduleTask implements SchedulingConfigurer {
// Obtain the execution period of the task from data
@Autowired
private MyBatisMapper myBatisMapper;
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(
//1. Add task content (Runnable)
Println (” Execute dynamic timed task: “+ localDatetime.now ().tolocalTime ()),
//2. Set the execution cycle (Trigger)
triggerContext -> {
//2.1 Obtain the execution period from the database
String cron = myBatisMapper.getCron();
//2.2 Return to Execution period (Date)
return new CronTrigger(cron).nextExecutionTime(triggerContext);
}
);
}
}
The database table data is as follows:
Now, let’s launch the test and see
Run a dynamic scheduled task at 17:17:00.008999
Run a dynamic scheduled task at 17:17:20.002501
Run a dynamic scheduled task at 17:17:30.001786
Run a dynamic scheduled task at 17:17:40.005512
Run a dynamic scheduled task at 17:17:50.005870
Run a dynamic scheduled task at 17:18:00.002189
Run a dynamic scheduled task at 17:18:10.001910
We can see that the mission is executed every 10 seconds. So now you want to do it every 5 seconds, what do you do? At this time, we only need to modify the database data, without restarting.
Now, what does the console print?
Run a dynamic scheduled task at 17:18:30.000902
Run a dynamic scheduled task at 17:18:40.001392
Run a dynamic scheduled task at 17:18:45.005027
Run a dynamic scheduled task at 17:18:50.001367
Run a dynamic scheduled task at 17:18:55.001356
Run a dynamic scheduled task at 17:19:00.001582
Run a dynamic scheduled task at 17:19:05.005676
Run a dynamic scheduled task at 17:19:10.001258
Execute a dynamic scheduled task at 17:19:15.005272
Success is executed every 5 seconds. Isn’t that a sense of accomplishment? Ha ha
4. A scheduled task whose time can be changed
Examples are as follows:
package com.nobody.task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
/ * *
* @description Specifies a scheduled task whose time can be dynamically changed
* @Author Mr.nobody
* @Date 2021/3/4
* @ Version 1.0.0
* /
@Component
public class ChangeTimeScheduledTask implements SchedulingConfigurer {
private static final Logger LOGGER = LoggerFactory.getLogger( ChangeTimeScheduledTask.class);
// Cron expression, we can dynamically change the value of this property to change the execution time of scheduled tasks
private String expression = “0/5 * * * * *”;
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
// The method to execute the scheduled task
Runnable task = () -> LOGGER.info(“>>> configureTasks …” );
// Scheduling implements time control
Trigger trigger = triggerContext -> {
CronTrigger cronTrigger = new CronTrigger(expression);
return cronTrigger.nextExecutionTime(triggerContext);
};
taskRegistrar.addTriggerTask(task, trigger);
}
public String getExpression() {
return expression;
}
public void setExpression(String expression) {
this.expression = expression;
}
}
Interface call:
package com.nobody.controller;
import com.nobody.task.ChangeTimeScheduledTask;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/ * *
* @Description
* @Author Mr.nobody
* @Date 2021/3/4
* @ Version 1.0.0
* /
@RestController
@RequestMapping(“demo”)
public class DemoController {
private ChangeTimeScheduledTask changeTimeScheduledTask;
public DemoController(final ChangeTimeScheduledTask changeTimeScheduledTask) {
this.changeTimeScheduledTask = changeTimeScheduledTask;
}
@GetMapping
public String testChangeTimeScheduledTask() {
changeTimeScheduledTask.setExpression(“0/10 * * * * *”);
return “ok”;
}
}
Scheduled tasks are executed every 5 seconds before the service is started and the interface is called
14:02:10 2021-03-04. 6836-001 the INFO [] TaskScheduler – 1 com. Nobody. Task. ChangeTimeScheduledTask: > > > configureTasks…
14:02:15 2021-03-04. 6836-001 the INFO [] TaskScheduler – 1 com. Nobody. Task. ChangeTimeScheduledTask: > > > configureTasks…
14:02:20 2021-03-04. 6836-002 the INFO [] TaskScheduler – 1 com. Nobody. Task. ChangeTimeScheduledTask: > > > configureTasks…
14:02:25 2021-03-04. 6836-001 the INFO [] TaskScheduler – 1 com. Nobody. Task. ChangeTimeScheduledTask: > > > configureTasks…
We then call the interface and change the timing of the scheduled task to one every 10 seconds.
14:02:30 2021-03-04. 6836-005 the INFO [] TaskScheduler – 1 com. Nobody. Task. ChangeTimeScheduledTask: > > > configureTasks…
14:02:35 2021-03-04. 6836-002 the INFO [] TaskScheduler – 1 com. Nobody. Task. ChangeTimeScheduledTask: > > > configureTasks…
14:02:40 2021-03-04. 6836-001 the INFO [] TaskScheduler – 1 com. Nobody. Task. ChangeTimeScheduledTask: > > > configureTasks…