1, Annotation based (@ Scheduled)
- Based on the annotation, @ Scheduled defaults to single thread. When multiple tasks are started, the execution time of the task is affected by the execution time of the previous task.
1. Create timer
- Using SpringBoot to create timed tasks based on annotations is very simple and can be completed in a few lines of code. The code is as follows:
import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import java.time.LocalDateTime; /** * @author zhaokuii11@163.com * @create 2022-01-11 14:53 * @Description */ @Configuration // 1. Represents that the current class is a configuration class @EnableScheduling // 2. Start scheduled task public class StaticScheduleTask { //3. Add Scheduled Task @Scheduled(cron = "0/5 * * * * ?") //Or directly specify the time interval, for example: 5 seconds //@Scheduled(fixedRate=5000) private void configureTask() { System.out.println("Time to execute static scheduled tasks" + LocalDateTime.now()); } }
1.2 Cron expression parameters respectively represent:
- Seconds (0 ~ 59), for example, 0 / 5 means every 5 seconds
- Min (0 ~ 59)
- Time (0 ~ 23)
- Day (0 ~ 31), to be calculated
- Month (0 ~ 11)
- Day of week (1-7 or SUN/MON/TUE/WED/THU/FRI/SAT can be filled)
- @Scheduled: in addition to the flexible parameter expression cron, it also supports simple delay operations, such as fixedDelay and fixedRate. Fill in the corresponding milliseconds.
# Cron expression example: Every 5 seconds:*/5 * * * * ? Every 1 minute: 0 */1 * * * ? Execute once at 23:00 every day: 0 0 23 * * ? Execute once every day at 1 a.m.: 0 0 1 * * ? Execute once at 1 a.m. on the 1st of each month: 0 0 1 1 * ? Execute once at 23:00 on the last day of each month: 0 0 23 L * ? Once every Sunday at 1 a.m.: 0 0 1 ? * L Once at 26, 29 and 33 points: 0 26,29,33 * * * ? At 0:00, 13:00, 18:00 and 21:00 every day: 0,13,18,21 * * ?
- More detailed cron parameters
https://blog.csdn.net/Qiwan2/article/details/89848298
https://blog.csdn.net/weixin_30720461/article/details/91388486
2, Interface based (schedulingconfigurator)
- Read the specified time from the database to dynamically execute the scheduled task. At this time, the interface based scheduled task comes in handy.
- Interface based (schedulingconfigurator)
2.1 dependency
<!--web starter--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--add to MySql rely on --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.45</version> <scope>runtime</scope> </dependency> <!--jdbc--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--add to Mybatis Dependency configuration mybatis Some initialization things--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency>
2.2 creating database
- Open the local database mysql, open the query window casually, and then execute the script as follows:
DROP DATABASE IF EXISTS `socks`; CREATE DATABASE `socks`; USE `SOCKS`; DROP TABLE IF EXISTS `cron`; CREATE TABLE `cron` ( `cron_id` varchar(30) NOT NULL PRIMARY KEY, `cron` varchar(30) NOT NULL ); INSERT INTO `cron` VALUES ('1', '0/5 * * * * ?');
# Connection parameter configuration spring.datasource.url=jdbc:mysql://localhost:3306/socks spring.datasource.password=root spring.datasource.username=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver
2.3 create timer
- After the database has prepared the data, we write the scheduled task. Note that the trigger task is added here to cycle read the execution cycle set in the database and the contents of the related scheduled tasks.
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import org.springframework.scheduling.support.CronTrigger; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.time.LocalDateTime; /** * @author zhaokuii11@163.com * @create 2022-01-11 15:10 * @Description */ @Configuration //1. It is mainly used to mark configuration classes and has the effect of Component @EnableScheduling //2. Start scheduled task public class DynamicScheduleTask implements SchedulingConfigurer { @Mapper public interface CronMapper { @Select("select cron from cron limit 1") public String getCron(); } @Resource CronMapper cronMapper; /** * Perform scheduled tasks * * @param scheduledTaskRegistrar */ @Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { scheduledTaskRegistrar.addTriggerTask( //1. Add task content (Runnable) () -> System.out.println("Dynamic scheduled tasks:" + LocalDateTime.now().toLocalTime()), //2. Set the execution cycle (Trigger) triggerContext -> { //2.1 obtaining execution cycle from database String cron = cronMapper.getCron(); //2.2 validity verification if (StringUtils.isEmpty(cron)) { // Omitted Code ... } //2.3 return execution cycle (Date) return new CronTrigger(cron).nextExecutionTime(triggerContext); }); } }
2.4 start up test
- After starting the application, check the console. The printing time is every 5 seconds as expected:
- Note: if the format is wrong when modifying the database, the scheduled task will stop, that is, the modification is correct again; You can only restart the project to recover at this time.
3, Setting multithreaded scheduled tasks based on annotations
- Two annotations are used here
@EnableAsync@Async https://www.cnblogs.com/hsug/p/13303018.html
@Async solves the problem of asynchronous calls https://www.cnblogs.com/mmzs/p/11557583.html
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.time.LocalDateTime; /** * @author zhaokuii11@163.com * @create 2022-01-11 18:55 * @Description */ @Component //@The Component annotation is used to annotate relatively neutral classes @EnableScheduling //1. Start scheduled task @EnableAsync //2. Enable multithreading public class MultithreadScheduleTask { @Async//3. @Async can define a thread task @Scheduled(fixedDelay = 1000) public void first() throws InterruptedException { System.out.println("The first scheduled task starts" + LocalDateTime.now().toLocalTime()); Thread.sleep(1000 * 10); } @Async @Scheduled(fixedDelay = 1000) public void second() throws InterruptedException { System.out.println("The second scheduled task starts" + LocalDateTime.now().toLocalTime()); System.out.println(); } }
- It can be seen from the console that the first scheduled task and the second scheduled task do not affect each other;
Moreover, since multithreading is enabled, the execution time of the first task is not limited by its own execution time, so it should be noted that repeated operations may lead to data exceptions.
reference resources