Spring @ Scheduled task scheduling

Posted by andym01480 on Tue, 01 Mar 2022 06:26:31 +0100

I Implementation mode of scheduled task

Implementation method of scheduled task:

  • Java comes with Java util. Timer class, which allows you to schedule a Java util. TimerTask task. In this way, you can make your program execute at a certain frequency, but it can't run at a specified time. Generally used less, this article will not be introduced in detail.
  • Using Quartz, this is a powerful scheduler that allows your program to execute at a specified time or at a certain frequency. The configuration is slightly complex. I have time to introduce it.
  • Use Spring's @ Scheduled annotation in conjunction with @ enableshcheduling.
  • SpringBoot comes with its own Scheduled, which can be regarded as a lightweight Quartz, and it is much simpler to use than Quartz. This article mainly introduces it.

Note: @ Scheduled annotation is used to mark that this method is a Scheduled task method, with multiple configurations. Cron supports cron expression, which specifies that the task will be executed at a specific time; fixedRate performs tasks at a specific frequency; fixedRateString configures the execution frequency in the form of string.

Scheduled task execution method:

  • Single thread (serial)
  • Multithreading (parallel)

II Create scheduled task

2.1 serial scheduling in Spring boot

Seheduled comes with Spring boot, which is easy to implement. You only need to add annotations to the methods that need to be scheduled. As follows:

package com.dxz.demo.schedule;
import java.time.LocalDateTime;

import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Service
//@Enablesscheduling can be omitted
public class PrintJob {

    @Scheduled(initialDelay=3000, fixedDelay = 10000)
    public void print() {
        Thread current = Thread.currentThread(); 
        System.out.println(LocalDateTime.now() + "  thread-name:" + current.getName() + ": 60 print");
    }
}

result:

2.2 parallel scheduling in Spring boot

Inherit the schedulengconfigurator class and override its method, as follows:

 

package com.dxz.demo.schedule;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }

    @Bean(destroyMethod = "shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(10);
    }
}

result:

Multiple threads execute scheduling according to a fixed frequency in turn.

2.3 asynchronous parallel scheduling in Spring boot

2.4. Spring parallel scheduling

1. Create a new web project and introduce spring related packages. pom files are as follows

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.dxz.demo</groupId>
    <artifactId>SpringDemo</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringDemo Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <finalName>SpringDemo</finalName>
    </build>
</project>

spring configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd">

    <import resource="applicationContext-task.xml" />
    <context:component-scan base-package="com.dxz.demo" />
</beans>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context.xsd 
    http://www.springframework.org/schema/task 
    http://www.springframework.org/schema/task/spring-task.xsd">

    <task:annotation-driven executor="taskExecutor"
        scheduler="taskScheduler" />
    <task:executor id="taskExecutor" pool-size="5" />
    <task:scheduler id="taskScheduler" pool-size="10" />
</beans>

web.xml configuration

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>appversion</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>

Scheduling task class

package com.dxz.demo;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class HelloWorldTask {
    @Scheduled(fixedRate = 5000)
    public void doSomething() throws Exception {
        System.out.println(Thread.currentThread().getName() + " doSomething is invoked!");
    }

    @Scheduled(fixedDelay = 5000)
    public void doSomething2() throws Exception {
        System.out.println(Thread.currentThread().getName() + " doSomething2 is invoked!");
    }
}

The engineering structure is as follows:

result:

As can be seen from the above figure, multiple threads are executing scheduling tasks.

III@ Scheduled Parameter Description:

Initial delay: indicates the delay time before the first run, in milliseconds
Fixed delay: indicates the interval from the completion of the previous task to the start of the next task. The unit is milliseconds.
Fixed rate: indicates the interval from the start of the previous task to the start of the next task. The unit is milliseconds. (if the execution of the previous task times out, the next task may be started immediately after the execution of the previous task is completed)
Cron: cron expression. (scheduled execution. If a scheduled interval cannot be executed due to the timeout of the previous task execution, the next scheduled interval will be postponed. The interval between the next task and the previous task is not fixed)
The difference is shown in the figure below:

4, Limitations - @ Scheduled cron cannot specify the year of execution

That is, if we use the following scheduled tasks

    @Scheduled(cron = "0 18 10 * * ? 2016-2016")
    public void testTaskWithDate() {
        logger.info("Test 2016.Scheduled task");
    }

The following error will be reported

Cron expression must consist of 6 fields (found 7 in "0 18 10 * * ? 2016-2016")

Caused by: java.lang.IllegalStateException: Encountered invalid @Scheduled method 'testTaskWithDate': Cron expression must consist of 6 fields (found 7 in "0 18 10 * * ? 2016-2016")
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:405)
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:258)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)

Error reason:

/**
 * Parse the given pattern expression.
 */
private void parse(String expression) throws IllegalArgumentException {
    String[] fields = StringUtils.tokenizeToStringArray(expression, " ");
    if (fields.length != 6) {
        throw new IllegalArgumentException(String.format(""
                + "cron expression must consist of 6 fields (found %d in %s)", fields.length, expression));
    }

spring , taks , does not support year timing. After all, it is not quartz, but a simple timing framework. Compared with jdk , Timer, it adds thread pool

However, there will be a problem when it is set to the year. When you start the project after this time, it will always report a memory leak error, which roughly means that your scheduled tasks will never be executed, resulting in the failure to start the project.

Comments in the source code:

 *The pattern is a list of six single space-separated fields: representing

 * second, minute, hour, day, month, weekday. Month and weekday names can be

 * given as the first three letters of the English names.

4, Detailed usage of Cron expression

Special characters allowed for field values
Seconds 0-59, - */
Points 0-59, - */
Hours 0-23, - */
Date 1-31, - */ L W C
Month 1-12 or JAN-DEC, - */
Monday 1-7 or sun-sat, - */ L C #
Year (optional) left blank, 1970-2099, - */
example:
0/5 * * * * ? : Every 5 seconds
The "*" character is used to specify all values. For example: "*" means "every minute" in the field of minutes.
“?” Characters are only used in date and week fields. It is used to specify "ambiguous values". It is useful when you need to specify something in one of these two fields. Look at the example below and you will understand.
The date in the month and the date in the week are mutually exclusive. You should set a question mark to indicate that you don't want to set that field.
The '-' character is used to specify a range. For example, "10-12" means "10:00, 11:00, 12:00" in small time domain.
The "," character is used to specify another value. For example, "MON,WED,FRI" means "Monday, Wednesday, Friday" in the week field.
The "/" character is used to specify the increment. For example, "0 / 15" in the second field means 0, 15, 30 and 45 seconds per minute. "5 / 15" represents 5, 20, 35 and 50 per hour in the minute field. The symbol "*" in front of "/" (e.g. * / 10) is equivalent to 0 in front of "/" (e.g. 0 / 10). Remember an essence: each numeric field of an expression is a set with maximum and minimum values. For example, the set of second field and minute field is 0-59, date field is 1-31, and month field is 1-12. The character "/" can help you get the corresponding value in each character field. For example, when "7 / 6" is in the month field, it will be triggered only in July, not every June.
L is the ellipsis of 'last'. It can represent the fields of day of month and day of week, but it has different meanings in the two fields. For example, the field of day of month represents the last day of a month. If it means' 7 'or' SAT 'in the day of week field, if it is preceded by a number in the day of week field, it means the last few days of a month. For example,' 6L 'means the last Friday of a month.
The character "W" is only allowed in the date field. This character is used to specify the most recent working day of the date. For example, if you write "15W" in the date field, it means the latest working day on the 15th of this month. Therefore, if the 15th is Saturday, the task will be triggered on the 14th. If 15 is Sunday, the task will be triggered on Monday, that is, the 16th. If "1W" is filled in the date field, even if the 1st is Saturday, the task will only be triggered on next Monday, that is, the 3rd. The latest working day specified by "W" character cannot cross months. The character "W" can only be used with a single value and cannot be a number field. For example, 1-15W is wrong.
"L" and "W" can be used together in the date field. LW represents the working day of the last week of the month.
The character "#" is only allowed in the week field. This character is used to specify a day of the month. For example: "6#3" means Friday in the third week of the month (6 means Friday and 3 means the third week). "2#1" means Monday in the first week of the month. "4#5" means Wednesday in the fifth week.
The character "C" is allowed in the date field and the week field. This character depends on a specified "calendar". That is, the value of this expression depends on the calculation result of the relevant calendar. If there is no calendar Association, it is equivalent to all the included calendars. For example, if the date field is "5C", it means the first day in the associated "calendar" or the next 5 days of the first day of the month. The week field "1C" indicates the first day in the associated calendar, or the day after the first day of the week, that is, the day after Sunday (Monday).

5, Expression example

"0 0 12 * * ?" Triggered at 12 noon every day
"0 15 10? * *" is triggered at 10:15 a.m. every day
"0 15 10 * * ?" Triggered every morning at 10:15
"0 * *? *" is triggered at 10:15 a.m. every day
"0 15 10 * *? 2005" triggered at 10:15 am every day in 2005
"0 * 14 * * ?" Triggered every 1 minute between 2 p.m. and 2:59 p.m. every day
"0 0/5 14 * * ?" Triggered every 5 minutes between 2 p.m. and 2:55 p.m. every day
"0 0/5 14,18 * * ?" Triggered every day between 6:00 p.m. and 2:55 p.m
"0 0-5 14 * * ?" Triggered every 1 minute between 2 p.m. and 2:05 p.m. every day
"0 10,44 14? 3 wed" is triggered at 2:10 PM and 2:44 pm on Wednesday in March every year
"0 15 10? * Mon-Fri" is triggered at 10:15 am from Monday to Friday
"0 15 10 15 * ?" Triggered at 10:15 am on the 15th of each month
"0 15 10 L * ?" Triggered at 10:15 am on the last day of each month
"0 15 10? * 6L" is triggered at 10:15 a.m. on the last Friday of each month
"0 15 10? * 6L 2002-2005" triggered at 10:15 am on the last Friday of each month from 2002 to 2005
"0 15 10? * 6#3" triggered at 10:15 am on the third Friday of each month

        
Common examples:

0 0 12 * * ?Triggered at 12:00 every day
0 15 10 ? * *Triggered at 10:15 every day
0 15 10 * * ?Triggered at 10:15 every day
0 15 10 * * ? *Triggered at 10:15 every day
0 15 10 * * ? 2005Triggered at 10:15 every day in 2005
0 * 14 * * ?Triggered every minute from 2:00 to 2:59 every afternoon
0 0/5 14 * * ?From 2:00 to 2:59 p.m. every day (starting at the hour and triggered every 5 points)
0 0/5 14,18 * * ?From 2:00 to 2:59 p.m. and from 18:00 to 18:59 p.m. every day (starting at the whole point and triggering every 5 points)
0 0-5 14 * * ?Triggered every minute from 2:00 to 2:05 every afternoon
0 10,44 14 ? 3 WEDMarch minute is triggered at 2:10 PM and 2:44 pm every Wednesday
0 15 10 ? * MON-FRITriggered at 10:15 a.m. every day from Monday to Friday
0 15 10 15 * ?Triggered at 10:15 a.m. on the 15th of each month
0 15 10 L * ?Triggered at 10:15 on the last day of each month
0 15 10 ? * 6LTriggered at 10:15 on Friday of the last week of each month
0 15 10 ? * 6L 2002-2005Triggered at 10:15 on Friday of the last week of each month from 2002 to 2005
0 15 10 ? * 6#3Triggered on Friday of the third week of each month
0 0 12 1/5 * ?Triggered every 5 days from the first noon of each month
0 11 11 11 11 ?Triggered at 11:11 on November 11 every year (Singles Day)

reference resources: http://wujq4java.iteye.com/blog/2067214

reference resources: http://blog.csdn.net/applebomb/article/details/52400154

Topics: Java Spring Spring Boot