Four ways for Spring Boot to implement timed tasks

Several ways to realize scheduled tasks:

Timer: This is java. Com that 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.

ScheduledExecutorService: also jdk's own class; It is a scheduled task class designed based on thread pool. Each scheduled task will be assigned to a thread in the thread pool for execution, that is, tasks are executed concurrently and do not affect each other.

Spring Task: Spring3. The task built after 0 can be regarded as a lightweight Quartz, and it is much simpler to use than Quartz.

Quartz: This is a powerful scheduler, which can let your program execute at a specified time or at a certain frequency. The configuration is slightly complicated.

Using Timer

This is currently used less in the project, and the demo code is pasted directly. You can check the api for specific introduction

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();

       //Schedule the specified task to start repeated fixed delay execution at the specified time. This is performed every 3 seconds
       timer.schedule(timerTask,10,3000);
   }

}

Using ScheduledExecutorService

This method is similar to Timer. Look at the demo directly:

public class TestScheduledExecutorService {

   public static void main(String[] args) {

       ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

       // Parameters: 1. Task body 2. Delay time of first execution
       // 3. Task execution interval 4. Interval time unit
       service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()), 0, 3, TimeUnit.SECONDS);

   }

}

Using spring tasks

Simple scheduled tasks

In the SpringBoot project, we can gracefully use annotations to implement scheduled tasks. First, create the project and import 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 task class:

@Slf4j

@Component

public class ScheduledService {

   @Scheduled(cron = "0/5 * * * * *")
   public void scheduled(){
       log.info("=====>>>>>use cron  {}",System.currentTimeMillis());
   }

   @Scheduled(fixedRate = 5000)
   public void scheduled1() {
       log.info("=====>>>>>use fixedRate{}", System.currentTimeMillis());
   }

   @Scheduled(fixedDelay = 5000)
   public void scheduled2() {
       log.info("=====>>>>>fixedDelay{}",System.currentTimeMillis());
   }

}

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

recommend: Spring quick start plan . It can be seen that all three scheduled tasks have been executed and executed in series in the same thread. If there is only one scheduled task, this is certainly no problem. When there are more scheduled tasks, if one task is stuck, other tasks will not be executed. Focus on the Java technology stack WeChat official account, reply the key word in the background: spring, you can get more Spring stack of dry cargo with long stack.

Multithreaded execution

In the traditional spring project, we can add the configuration of task in the xml configuration file, while in the SpringBoot project, we usually use the config configuration class to add the configuration, so we create an AsyncConfig class. Focus on the Java technology stack WeChat official account, reply the key word in the background: spring, you can get more Spring stack of dry cargo with long stack.

@Configuration
@EnableAsync
public class AsyncConfig {

    /*
     *Here, the member variable should be read from the configuration using @ 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. Each thread is restarted in a different project.

Configuration of execution time

In the above Scheduled task, we use the @ Scheduled annotation to set the execution time of the task, and use three attribute configuration methods:

fixedRate: defines a scheduled task to be executed at a certain frequency

fixedDelay: defines a scheduled task to be executed at a certain frequency. The difference is that the attribute can be changed in conjunction with initialDelay to define the execution delay of the task.

cron: configure task execution time through expression

Detailed explanation of cron expression

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

Seconds (0 ~ 59)

Minutes (0 ~ 59)

Hours (0 ~ 23)

Days (0 ~ 31)

Month (0 ~ 11)

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 every 4 hours), a list (1,3,5), and wildcards. Because the two elements "date in month" and "date in week" are mutually exclusive, one of them must be set. recommend: Spring quick start plan.

**Configuration instance:
**

Every 5 seconds: / 5 *?

Every 1 minute: 0 / 1?

0 0 10,14,16 ? Every day at 10 a.m., 2 p.m. and 4 p.m

0 0/30 9-17 ? Every half an hour during nine to five working hours

0 0 12 ? * WED means 12 noon every Wednesday

“0 0 12 ?” Triggered at 12 noon every day

"0 15 10?" triggered every morning at 10:15

“0 15 10 ?” Triggered every morning at 10:15

"0 15 10? *" 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 5 minutes between 2 p.m. and 2:55 p.m. and between 6 p.m. and 6: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

Some subexpressions can contain ranges or lists

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

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

For example, "0 / 15" in the subexpression (minute) means every 15 minutes starting from the 0th minute
"3 / 20" in the subexpression (minutes) means every 20 minutes from the third minute (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 sub expressions is assigned a value, in order to avoid conflict, you need to set the value of the other sub expression to "

The "L" character is only used in the two subexpressions of day (month) and day (week). It is the abbreviation of the word "last"
If there is specific content before "L", it has other meanings.

For example, "6L" means the penultimate day of the month
Note: when using the "L" parameter, do not specify a list or range, as this can cause problems

The W character represents mon FRI and can only be used in the day field. It is used to specify the nearest weekday from the specified day. Most business processing is based on the work week, so the W character may be very important.

For example, 15W in the daily domain means "the nearest weekday from the 15th of the month." If the 15th is Saturday, the trigger will be triggered on the 14th (Friday), because Thursday is closer to the 15th than Monday.

C: Stands for "Calendar". It means the date associated with the plan. If the date is not associated, it is equivalent to all the dates in the Calendar.

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

Integrate Quartz

===========

Add dependency

If the SpringBoot version is later than 2.0.0, the spring boot starter includes the dependency of quart. You can directly use the spring boot starter quartz dependency:

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

For 1.5.9, add dependencies using the following:

<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>

The version of SpringBoot I use here is 2.0.0 Build-snapshot, this version began to integrate Quartz, so it is very convenient to implement. Others seem to be troublesome. I won't introduce them here. I'll have time to learn more about Quartz in detail in the future.

Create a task class TestQuartz, which mainly inherits QuartzJobBean

public class TestQuartz extends QuartzJobBean {

    /**
     * Perform scheduled tasks
     * @param jobExecutionContext
     * @throws JobExecutionException
     */

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        System.out.println("quartz task "+new Date());

    }

}

Create configuration class 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)  //Set the time period in seconds
                .repeatForever();
        return TriggerBuilder.newTrigger().forJob(teatQuartzDetail())

                .withIdentity("testQuartz")
                .withSchedule(scheduleBuilder)
                .build();

    }

}

Start project

The above is a brief introduction to the processing of SpringBoot scheduled tasks. The direct use of SpringTask annotation should be the most convenient, and the use of Quartz has become very convenient since 2.0. For these two methods, it should be said that each has its own advantages. Choose as needed. In addition, you can check the official documents for details about Quartz

 

Keywords: Spring Boot

Added by newman on Tue, 08 Mar 2022 08:58:20 +0200