ip696
ip696

Reputation: 7084

How can I start @Scheduled method with concrete scheduler?

I have scheduler:

@Bean("one")
ThreadPoolTaskScheduler taskScheduler(){
    ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    threadPoolTaskScheduler.setPoolSize(5);
    threadPoolTaskScheduler.setAwaitTerminationSeconds(60);
    threadPoolTaskScheduler.setThreadNamePrefix("Test-");
    return threadPoolTaskScheduler;
}

@Bean("two")
ThreadPoolTaskScheduler taskScheduler2(){
    ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    threadPoolTaskScheduler.setPoolSize(50);
    threadPoolTaskScheduler.setAwaitTerminationSeconds(60);
    threadPoolTaskScheduler.setThreadNamePrefix("Test2-");
    return threadPoolTaskScheduler;
}

And method:

@Scheduled(fixedRate = 1000L)
public void test() {

And Second method:

@Scheduled(fixedRate = 1000L)
public void test2() {

How can I configure each @Scheduled method with concrete scheduler?

If I implement it like this:

@Slf4j
@Component
public class MyScheduler {

    private final ThreadPoolTaskScheduler taskSchedulerFirst;
    private final ThreadPoolTaskScheduler taskSchedulerSecond;
    private final TestBean testBean;

    public MyScheduler(@Qualifier("first") ThreadPoolTaskScheduler taskSchedulerFirst, @Qualifier("second")ThreadPoolTaskScheduler taskSchedulerSecond, TestBean testBean) {
        this.taskSchedulerFirst = taskSchedulerFirst;
        this.taskSchedulerSecond = taskSchedulerSecond;
        this.testBean = testBean;
    }

    @PostConstruct
    public void test() {
        taskSchedulerFirst.scheduleAtFixedRate(testBean::test, 1000L);
        taskSchedulerSecond.scheduleAtFixedRate(testBean::test2, 1000L);
    }

Bouth schedulers not used and used TaskExecutor:

2018-09-05 11:10:30.812  INFO 10724 --- [TaskExecutor-41] com.example.scheduling.TestBean          : hz
2018-09-05 11:10:31.747  INFO 10724 --- [TaskExecutor-43] com.example.scheduling.TestBean          : hz
2018-09-05 11:10:31.748  INFO 10724 --- [TaskExecutor-46] com.example.scheduling.TestBean          : hz2
2018-09-05 11:10:32.747  INFO 10724 --- [TaskExecutor-45] com.example.scheduling.TestBean          : hz
2018-09-05 11:10:32.748  INFO 10724 --- [TaskExecutor-48] com.example.scheduling.TestBean          : hz2
2018-09-05 11:10:33.747  INFO 10724 --- [TaskExecutor-47] 

But used TaskExecutor why?

Upvotes: 3

Views: 380

Answers (3)

dpr
dpr

Reputation: 10964

When using the @Scheduled annotation there is no out-of-the-box support to use different thread pools for different beans. You can configure the thread pool to be used by implementing SchedulingConfigurer in your @Configuration class.

I think the implementation after your edit should work. You probably only need to call threadPoolTaskScheduler.initialize() directly after creating the scheduler like this:

@Bean("two")
ThreadPoolTaskScheduler taskScheduler2(){
    ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    threadPoolTaskScheduler.initialize(); // initialize scheduler
    threadPoolTaskScheduler.setPoolSize(50);
    threadPoolTaskScheduler.setAwaitTerminationSeconds(60);
    threadPoolTaskScheduler.setThreadNamePrefix("Test2-");
    return threadPoolTaskScheduler;
}

This will create the scheduler's internal executor, that is used the actually execute stuff.

Upvotes: 1

Rohit
Rohit

Reputation: 2152

You need to implement the SchedulingConfigurer in config class and override it's configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) method. In the overridden method register your ThreadPoolTaskScheduler:

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    ...

        scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }

Upvotes: 0

Ori Marko
Ori Marko

Reputation: 58774

TL;DR No

According to Spring scheduling they are different implementations of TaskScheduler abstraction

  1. ThreadPoolTaskScheduler as implementation:

    ThreadPoolTaskScheduler, can be used whenever external thread management is not a requirement. Internally, it delegates to a ScheduledExecutorService instance. ThreadPoolTaskScheduler actually implements Spring's TaskExecutor interface as well, so that a single instance can be used for asynchronous execution as soon as possible as well as scheduled, and potentially recurring, executions.

  2. @Scheduled as annotation support for task scheduling

The @Scheduled annotation can be added to a method along with trigger metadata.

See also answer for best way to schedule task , most voted:

The simplest way to schedule tasks in Spring is to create method annotated by @Scheduled in spring managed bean.

Upvotes: 2

Related Questions