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…