Java – run each spring scheduler in its own thread

I have multiple components with @ scheduled annotation, and I find that spring starts only one at a time, even if they are scheduled to run at the same time

My use case is as follows I want each @ scheduled annotation to run in its own thread, but each thread only runs once

Given this pseudo code with two schedulers:

@Scheduled(cron = "0 * * * * *") //run every minute
public void methodA() {
   log.info("Running method A");
   executeLongRunningJob("Finished method A");
}

@Scheduled(cron = "0 * * * * *") //run every minute
public void methodB() {
   log.info("Running method B");
   executeLongRunningJob("Finished method B");       
}

private void executeLongRunningJob(String msg) {
    Thread.sleep(70 seconds);
    System.out.println(msg);
}

Note that this task takes longer than the scheduled scheduler to run This is crucial I don't want the scheduler to restart before it finishes running

Running this code out of the box gives me the following output:

Running method A
Finished method A
Running method B
Finished method B
Running method A
Finished method A
Running method B
Finished method B
... and so on

Obviously, it runs two schedulers in one thread

When I put @ async on my expensive method, I almost got the right behavior, except that I didn't complete the expensive method before the new scheduler started

Running method A
Running method B
Running method A
Running method B
Finished method A
Finished method B
... and so on

What I want is this output:

Running method A  
Running method B
Finished method A 
Finished method B 
Running method A 
Running method B 
Finished method A 
Finished method B
... and so on

How can I do that? I want each scheduler to run at the same time, but wait until it is complete before allowing it to run again Remember, I have more than two schedulers running at the same and sometimes different times

Solution

You're right - by default, the scheduler uses a thread pool of size 1, so each task is processed sequentially You can do this by configuring the taskscheduler bean with the required pool size Consider the following examples:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import java.util.Date;

@SpringBootApplication
@EnableScheduling
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }

    @Bean
    public TaskScheduler taskScheduler() {
        final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10);
        return scheduler;
    }


    @Scheduled(fixedDelay = 2 * 1000L,initialDelay = 3 * 1000L)
    public void scheduled1() throws InterruptedException {
        System.out.println(new Date() + " " + Thread.currentThread().getName() + ": scheduled1");
        Thread.sleep(1000);
    }

    @Scheduled(fixedDelay = 3 * 1000L,initialDelay = 3 * 1000L)
    public void scheduled2() throws InterruptedException {
        System.out.println(new Date() + " " + Thread.currentThread().getName() + ": scheduled2");
        Thread.sleep(1000);
    }
}

It will run each scheduled task in a separate thread, for example:

Tue Jul 18 20:21:50 CEST 2017 taskScheduler-1: scheduled2
Tue Jul 18 20:21:50 CEST 2017 taskScheduler-2: scheduled1
Tue Jul 18 20:21:53 CEST 2017 taskScheduler-1: scheduled1
Tue Jul 18 20:21:54 CEST 2017 taskScheduler-3: scheduled2
Tue Jul 18 20:21:56 CEST 2017 taskScheduler-2: scheduled1
Tue Jul 18 20:21:58 CEST 2017 taskScheduler-4: scheduled2
Tue Jul 18 20:21:59 CEST 2017 taskScheduler-1: scheduled1
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>