Home  >  Article  >  Java  >  How to implement several scheduled tasks in Spring Boot

How to implement several scheduled tasks in Spring Boot

Java后端技术全栈
Java后端技术全栈forward
2023-08-15 16:50:341344browse

In actual development, we will more or less use some scheduled task scenarios. This article will talk about commonly used scheduled tasks.

Commonly used timing task implementation solutions include the following:

  • Timer: This is the java.util.Timer class that comes with java. This class allows you to schedule a java.util.TimerTask task. Using this method allows your program to be executed at a certain frequency, but not at a specified time. Generally used less.
  • ScheduledExecutorService: It is also a class that comes with jdk; it is a scheduled task class based on the thread pool design. Each scheduled task will be assigned to a thread pool Threads are executed, that is to say, tasks are executed concurrently and do not affect each other.
  • Spring TaskSpring3.0For future tasks, you can regard it as a lightweight Quartz and use It's much simpler than Quartz.
  • Quartz: This is a relatively powerful scheduler that allows your program to be executed at a specified time or at a certain frequency. The configuration is a bit complicated.
  • In the database, create a table and store cron expressions in the table.
  • nacos, using distributed configuration to implement dynamic configuration cron expression.
  • XXL-JOB, distributed task

Use Timer

This is currently rarely used in projects, and the demo code is posted directly.

For a detailed introduction, please view the API:

public class TestTimer {
    public static void main(String[] args) {
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("task  run:"+ new Date());
            }
        };
        Timer timer = new Timer();
        //安排指定的任务在指定的时间开始进行重复的固定延迟执行。这里是每3秒执行一次
        timer.schedule(timerTask,10,3000);
    }
}

Use ScheduledExecutorService

This method is similar to Timer, just look at the demo:

public class TestScheduledExecutorService {
    public static void main(String[] args) {
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        // 参数:1、任务体 2、首次执行的延时时间
        //      3、任务执行间隔 4、间隔时间单位
        service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()), 0, 3, TimeUnit.SECONDS);
    }
}

Use Spring Task

Simple scheduled tasks

In the Spring Boot project, we can use annotations to implement scheduled tasks very elegantly. First, create the project and import the dependencies:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
  </dependency>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

Create a task class:

@Slf4j
@Component
public class ScheduledService {
    @Scheduled(cron = "0/5 * * * * *")
    public void scheduled(){
        log.info("=====>>>>>使用cron  {}",System.currentTimeMillis());
    }
    @Scheduled(fixedRate = 5000)
    public void scheduled1() {
        log.info("=====>>>>>使用fixedRate{}", System.currentTimeMillis());
    }
    @Scheduled(fixedDelay = 5000)
    public void scheduled2() {
        log.info("=====>>>>>fixedDelay{}",System.currentTimeMillis());
    }
}

Use the @EnableScheduling annotation on the main class to enable support for scheduled tasks, and then start the project

How to implement several scheduled tasks in Spring Boot

You can see When all three scheduled tasks have been executed, and they are executed serially in the same thread, if there is only one scheduled task, this will definitely be fine. When the number of scheduled tasks increases, if one task is stuck, other tasks will not be able to execute.

Multi-threaded execution

In traditional Spring projects, we can add task configuration in the xml configuration file, while in Spring Boot projects we generally use the config configuration class to add configuration, so Create a new AsyncConfig class

@Configuration
@EnableAsync
public class AsyncConfig {
     /*
    此处成员变量应该使用@Value从配置中读取
     */
    private int corePoolSize = 10;
    private int maxPoolSize = 200;
    private int queueCapacity = 10;
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.initialize();
        return executor;
    }
}

@Configuration: Indicates that this class is a configuration class@EnableAsync: Enables support for asynchronous events

Then add @Async to the class or method of the scheduled task. Finally restart the project, each task is in a different thread.

How to implement several scheduled tasks in Spring Boot

Configuration of execution time

In the above scheduled task, we use the @Scheduled annotation on the method to set the execution time of the task, and use three A property configuration method:

  1. fixedRate: Define a scheduled task that is executed at a certain frequency
  2. fixedDelay: Define a scheduled task that is executed at a certain frequency. The difference from the above is that, The attribute can be changed in conjunction with initialDelay to define the delayed execution time of the task.
  3. cron: Configure task execution time through expressions

Detailed explanation of cron expression

A cron expression has at least 6 (possibly 7) space-separated time elements. In order:

  • seconds (0~59)
  • ## minutes (0~59)
  • 3 hours (0~23)
  • 4 days (0~31)
  • 5 months (0~11)
  • 6 Week (1~7 1=SUN or SUN, MON, TUE, WED, THU, FRI, SAT)
  • Year (1970- 2099)
Each element can be a value (such as 6), a continuous interval (9-12), an interval (8-18/4) (/ means each 4 hours apart), a list (1,3,5), wildcard. Since the two elements "day of month" and "day of week" are mutually exclusive, one of them must be set. Configuration example:

  • Execute every 5 seconds: */5* * ?
  • Execute every 1 minute: 0 /1 ?
  • 0 0 10,14,16 ? Every day 10 am, 2 pm, 4 pm
  • 0 0/30 9- 17 ? Every half hour during 9 to 5 working hours
  • 0 0 12 ? *WED means every Wednesday at 12 noon
  • " 0 0 12 ?" Triggered every day at 12 noon
  • "0 15 10 ? "Triggered every day at 10:15 am
  • "0 15 10 ?" Triggers every day at 10:15 AM
  • ##"0 15 10 ? *" Triggers every day at 10:15 AM
  • "0 15 10 ? 2005" Triggered every day at 10:15 AM in 2005
  • "0
    14 * ?" every 1 minute from 2 PM to 2:59 PM every day Trigger
  • ##"0 0/5 14 ?" Trigger every 5 minutes from 2pm to 2:55pm every day
  • " 0 0/5 14,18 ?" Trigger every 5 minutes from 2pm to 2:55pm and every 5 minutes from 6pm to 6:55pm
  • "0 0-5 14 ?" Fires every 1 minute between 2pm and 2:05pm every day
  • "0 10,44 14 ? 3 WED" Every Wednesday in March at 2pm: Triggers at 10 and 2:44
  • "0 15 10 ? * MON-FRI" Triggers at 10:15 am from Monday to Friday
  • "0 15 10 15 * ?" Triggers at 10:15 am on the 15th of each month
  • "0 15 10 L * ?" Triggers at 10:15 am on the last day of each month
  • "0 15 10 ? * 6L" Triggered at 10:15 am on the last Friday of every month
  • "0 15 10 ? * 6L 2002- 2005" Triggered on the last Friday of each month at 10:15 AM from 2002 to 2005
  • "0 15 10 ? * 6#3" On the third Friday of each month at 10 AM :15 trigger
  • Some subexpressions can contain some ranges or lists

For example: the subexpression (day (week)) can be "MON- FRI", "MON, WED, FRI", "MON-WED,SAT"

The "*" characters represent all possible values The "/" character is used to specify the increment of the value

For example: "0/15" in the subexpression (minutes) means starting from minute 0, every 15 minutes "3/20" in the subexpression (minutes) means that starting from the 3rd minute, every 20 minutes (it has the same meaning as "3, 23, 43")

"?" The character is only used in the two sub-expressions of day (month) and day (week), indicating that no value is specified. When one of the two subexpressions is assigned a value, in order to avoid conflicts, the value of the other subexpression needs to be set to "?"

The "L" character is only used for days (months) and day (week) are two subexpressions, which are the abbreviation of the word "last" If there is something specific before the "L", it has other meanings.

For example: "6L" means the sixth to last day of this month Note: When using the "L" parameter, do not specify a list or range, as this will cause problems

The W character represents weekdays (Mon-Fri) and can only be used in the day domain. It is used to specify the closest weekday to the specified date. Most business processing is based on the work week, so the W character can be very important.

For example, 15W in the day field means "the closest weekday to the 15th of the month." If the 15th is a Saturday, then the trigger will be triggered on the 14th (Friday), because Thursday is smaller than Monday is closer to the 15th.

C: stands for "Calendar". It means the date associated with the schedule, or all dates in the calendar if the date is not associated.

For example, 5C in the date field is equivalent to the first day after the 5th in the calendar. 1C in the day of the week field corresponds to the first day after Sunday.

##Seconds0~59, - * /##Minuteshours# #Date1-31, - * ? / L W C1~12 or JAN~DEC1~7 or SUN~SATLeave blank, 1970~2099
Fields Allowed values ​​ Allowed special characters
0~59 , - * /
0~23 , - * /
##month
, - * / weekday
, - * ? / L C #Year (optional)
, - * /

在线cron表达式生成:http://qqe2.com/cron/index

整合Quartz

  • 添加依赖

如果Spring Boot版本是2.0.0以后的,则在spring-boot-starter中已经包含了quart的依赖,则可以直接使用spring-boot-starter-quartz依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

如果是1.5.9则要使用以下添加依赖:

<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz</artifactId>
  <version>2.3.0</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
</dependency>

这里我使用Spring Boot版本是2.0.0.BUILD-SNAPSHOT ,该版本开始集成了Quartz,所以事实现起来很方便。其它好像比较麻烦,这里就不介绍,以后有时间再详细深入了解Quartz。

  • 创建任务类TestQuartz,该类主要是继承了QuartzJobBean
public class TestQuartz extends QuartzJobBean {
    /**
     * 执行定时任务
     * @param jobExecutionContext
     * @throws JobExecutionException
     */
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("quartz task "+new Date());
    }
}
  • 创建配置类QuartzConfig
@Configuration
public class QuartzConfig {
    @Bean
    public JobDetail teatQuartzDetail(){
        return JobBuilder.newJob(TestQuartz.class).withIdentity("testQuartz").storeDurably().build();
    }

    @Bean
    public Trigger testQuartzTrigger(){
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(10)  //设置时间周期单位秒
                .repeatForever();
        return TriggerBuilder.newTrigger().forJob(teatQuartzDetail())
                .withIdentity("testQuartz")
                .withSchedule(scheduleBuilder)
                .build();
    }
}
  • 启动项目

How to implement several scheduled tasks in Spring Boot

最后

上面都是简单的介绍了关于Spring Boot定时任务的处理,直接使用SpringTask注解的方式应该是最方便的,而使用Quartz从2.0开始也变得很方便。对于这两种方式,应该说各有长处吧,按需选择。

The above is the detailed content of How to implement several scheduled tasks in Spring Boot. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:Java后端技术全栈. If there is any infringement, please contact admin@php.cn delete