spring boot default single thread queuing run timing task problem record

Posted by anakadote on Sat, 14 Dec 2019 16:03:57 +0100

**Problem Description: when using the default scheduled tasks of springboot, if there are multiple tasks, the framework will only start one thread for execution by default, which will cause some tasks cannot start execution at the specified time**

**In addition, a separate record will be written about the synchronization lock of timed tasks under distributed environment**

Test the thread name of the scheduled task by default:

package com.example.demo.job;

import net.javacrumbs.shedlock.core.SchedulerLock;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Component
@EnableScheduling
public class TestJob {


    @Scheduled(cron = "0/5 * * * * ?")
    @SchedulerLock(name = "test1-task", lockAtMostForString = "PT28M", lockAtLeastForString = "PT28M")
    public void execute1() {
        String curName = Thread.currentThread().getName();
        System.out.println("current time:" + LocalDateTime.now() + "  task execute1 Corresponding thread name: " + curName);
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Scheduled(cron = "0/5 * * * * ?")
    @SchedulerLock(name = "test2-task", lockAtMostForString = "PT28M", lockAtLeastForString = "PT28M")
    public void execute2() {

        String curName = Thread.currentThread().getName();
        System.out.println("current time:" + LocalDateTime.now() + "  task execute2 Corresponding thread name: " + curName);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Scheduled(cron = "0/10 * * * * ?")
    @SchedulerLock(name = "test3-task", lockAtMostForString = "PT28M", lockAtLeastForString = "PT28M")
    public void execute3() {

        String curName = Thread.currentThread().getName();
        System.out.println("current time:" + LocalDateTime.now() + "  task execute3 Corresponding thread name: " + curName);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

The results are as follows:

By default, there is only one thread for the timing task of spring boot:

In this case, if some scheduled tasks are set to start execution at a certain fixed time, it may occur that they need to be queued and cannot be executed on time. Then I found the following solution. I don't really want Barra's source code. Everyone picked it up on the Internet, that is, initializing a thread for null, and directly click on the solution:

Add the following code to the startup class:

/**
	 *  Solve the single thread queuing problem of timed tasks and establish thread pool
	 * @return
	 */
	@Bean
	public TaskScheduler taskScheduler() {
		ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
		taskScheduler.initialize();
		taskScheduler.setPoolSize(50);
		return taskScheduler;
	}

Then restart to see how the thread works:

And the number of core threads:

This solves the single thread problem.

Another: only one scheduled task can be executed in the distributed situation. There are many schemes to prevent repeated execution. Write again next time.

Topics: Programming SpringBoot Java Spring