3

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?

dpr
  • 10,591
  • 3
  • 41
  • 71
ip696
  • 6,574
  • 12
  • 65
  • 128
  • Did you remove the `@Scheduled` annotation from the bean methods after your edit? – dpr Sep 05 '18 at 08:49
  • bean methods after not @Scheduled befour and after edit. Only Async – ip696 Sep 05 '18 at 09:11
  • You should not need the `@Async` annotation. This will make spring use a different thread pool for execution. Simply remove this annotation an you should be fine. – dpr Sep 05 '18 at 09:23

3 Answers3

2

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.

Ori Marko
  • 56,308
  • 23
  • 131
  • 233
  • I did not understand anything from the answer. somehow all smeared. Can I set concrete tasckScheduler to method with @Scheduled annotation or not? – ip696 Sep 05 '18 at 08:16
  • @ip696 TL;DR No, they are different implementation of scheduling – Ori Marko Sep 05 '18 at 08:17
  • but if I configure 1 tasckScheduler and one @Scheduled method - this method use this tasckScheduler. – ip696 Sep 05 '18 at 08:23
1

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.

dpr
  • 10,591
  • 3
  • 41
  • 71
0

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);
    }
Rohit
  • 2,132
  • 1
  • 15
  • 24