SpringBoot integrated task Scheduler

SpringBoot integrated task Scheduler

Basic steps

  • Step 1: introduce pom dependency
    <!--Support task scheduling-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-quartz</artifactId>
    </dependency>
  • Step 2: enable Task Scheduling Support
@EnableScheduling
public class RootConfig {
}
  • Step 3: custom class
@Component
public class ScheduleJob {
    /**
     * Every two seconds
     * fixedDelay: The interval is counted according to the end of the last task
     *      2022-05-07T22:01:53.025288100----------
     *      2022-05-07T22:02:00.027980700----------
     *      2022-05-07T22:02:07.031691200----------
     * fixedRate: The interval is timed according to the start of the last task, which is easy to cause thread blocking
     *      2022-05-07T22:05:01.320040600----------
     *      2022-05-07T22:05:06.320986600----------
     *      2022-05-07T22:05:11.321895300----------
     */
//    @Scheduled(fixedDelay = 2,timeUnit = TimeUnit.SECONDS)
    @Scheduled(fixedRate = 2,timeUnit = TimeUnit.SECONDS)
    public void testSchedule() throws InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        System.out.println(LocalDateTime.now()+"----------");
    }
}

Scheduled annotation

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
    //cron expressions 
    String cron() default "";
	//Unit: default millisecond
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
}

@How can Scheduled(fixedRate) avoid blocking tasks

Add the annotation @ EnableAsync (on the class) and @ Async (on the method). After adding the annotation, the multithreading mode is enabled. When it comes to the execution time of the next task, if the last task has not been executed, a new thread will be automatically created to execute it. Asynchronous execution can also be understood as ensuring that tasks are executed at a fixed speed.

When multithreading is enabled, the interval between the start of each task is 5 seconds. This is in line with our expectations, but there are still some defects in the end. In this case, the thread is destroyed as soon as the task is executed. Create another program when necessary next time. Every time you have to recreate it, it obviously affects the performance, so you need to give it a thread pool in the code.

  • Create thread pool
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(5);
        return taskScheduler;
    }

Solve thread blocking problem

@Component
@EnableAsync
public class ScheduleJob {
    
    @Scheduled(fixedRate = 2,timeUnit = TimeUnit.SECONDS)
    @Async
    public void testSchedule() throws InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        System.out.println(LocalDateTime.now()+"----------");
    }
}

The implementation results are as follows

2022-05-07T22:20:48.117983200----------
2022-05-07T22:20:50.072179500----------
2022-05-07T22:20:52.067858600----------
2022-05-07T22:20:54.067964400----------
2022-05-07T22:20:56.067006800----------

Differences between fixedRate and fixedDelay:

fixedDelay is very easy to understand. Its interval is timed according to the end of the last task. For example, if fixedDelay=5*1000 is set on a method, the time will be calculated after a certain execution of the method. When the time reaches 5 seconds, the method will be executed again.

fixedRate is troublesome to understand. Its interval is timed according to the start of the last task. For example, when fiexdRate=51000 is set on the method, the time taken to execute the method is 2 seconds, and the method will be executed again after 3 seconds.
But there is a pit here. When the task execution time exceeds the set interval time, what will be the result. For example, a task takes only 2 seconds to complete. I set fixedRate=51000, but the task takes 7 seconds to complete due to network problems. When the task starts, Spring will time the task. After 5 seconds, Spring will call the task again, but it is found that the original task is still executing. At this time, the second task is blocked (only considering the case of single thread). Even if the first task takes too long, the third and fourth tasks may be blocked. Blocked tasks are like people in a queue. Once the previous task is gone, it will be executed immediately.

cron expressions

wildcard

CompanySymbol support
second, - * /
branch, - * /
Time, - * /
day, - * / L W
month, - * /
Week / week, - * / L # only # represents week, others represent week

,: indicates enumeration, for example, 1, 2, 3

-Identification: continuous, e.g. 3-5

*: indicates every second, minute

/: indicates the interval. For example, 1 / 3 starts from 1 second and every 3 seconds

50: Indicates the last, e.g. L

W: Specify the closest working day, such as 2W

#: Specifies the day of the week, for example 3#2
Only # represents week, others represent week

?: It can be used in a day or week to indicate that it is not specified

    /**
     * The task is performed at 1,2,3 seconds of each minute at 22:00 every day in May
     * Second minute hour day month week / week
     * @throws InterruptedException
     */
    @Scheduled(cron = "1,2,3 * 22 * 5 ?")
    public void testSchedule2() throws InterruptedException {
        System.err.println(LocalDateTime.now()+"===========");
    }

Multithreading

    /**
     * Multithreading executes tasks once per second
     * @throws InterruptedException
     */
    @Scheduled(cron = "* * * * * ?")
    public void testSchedule3() throws InterruptedException {
        System.err.println(Thread.currentThread()+"-"+LocalDateTime.now()+"\\\\\\\\");
    }
  • yml number of thread pools created
spring:
  task:
    scheduling:
      pool:
        size: 5

Official reference documents

https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#scheduling-annotation-support

Tags: Java Spring Spring Boot

Posted by denzlite on Tue, 17 May 2022 01:24:21 +0300