2

I have a scheduled task which needs to launch multiple threads of the same process when executed, is it possible to set a specific number of threads to be launched when the process is kicked off?

In the application class I have the following TaskExecutor beans configured

    @Bean("threadFooExecutor")
    public TaskExecutor getFooExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(20);
        executor.setMaxPoolSize(1000);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setThreadNamePrefix("Foo-");
        return executor;
    }```

    @Bean("threadBarExecutor")
    public TaskExecutor getBarExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(20);
        executor.setMaxPoolSize(1000);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setThreadNamePrefix("Bar-");
        return executor;
    }

Async processes configured in process class

    @Async("threadFooExecutor")
    @Scheduled(fixedRate = 3000, initialDelay = 5000)
    public void print() {
        System.out.println(Thread.currentThread().getName() + " " + 1);
        System.out.println(Thread.currentThread().getName() + " " + 2);
        System.out.println(Thread.currentThread().getName() + " " + 3);
        System.out.println(Thread.currentThread().getName() + " " + 4);
    }

    @Async("threadBarExecutor")
    @Scheduled(fixedRate = 3000, initialDelay = 5000)
    public void print2() {
        System.out.println(Thread.currentThread().getName() + " " + 1);
        System.out.println(Thread.currentThread().getName() + " " + 2);
        System.out.println(Thread.currentThread().getName() + " " + 3);
        System.out.println(Thread.currentThread().getName() + " " + 4);
    }

What I would like to see is 2 or 3 of each of these threads running at the same time, but I only see each thread being run once every 3 seconds

2 Answers 2

1

I think that you mix things : TaskExecutor/Executor configuration and the frequency rate of the tasks executed by the scheduler.

This configuration means that the task will be executed every 3 seconds :

@Scheduled(fixedRate = 3000, ...)

Adding that : @Async("threadBarExecutor") just means that the Scheduler will use a specific Executor to run the tasks.

It doesn't mean that it will be executed as much as the thread pool size is not full in the configured Executor.
So yes it looks normal that these two tasks be triggered every 3 seconds.

If you want to run these tasks a specific number of times in parallel and every 3 seconds, @Scheduled is not enough.
You should make the scheduler method to invoke another @Asynch method. This can be defined in the same bean or in another, you don't matter.

@Async("threadFooExecutor")
@Scheduled(fixedRate = 3000, initialDelay = 5000)
public void printRepeat3Times() {
    for (int i=0; i<3; i++){
         print();
    }
}


@Async("threadFooExecutor")
public void print() {
     // ...
}

Note that as these methods are annotated with @Asynch, print() invocations don't "block" the current thread and so these could be executed in parallel thanks to the ExecutorService under the hoods.

Sign up to request clarification or add additional context in comments.

3 Comments

These tasks are supposed to be scheduled, I am busy with a project which requires me to schedule these processes and kick off multiple threads. ie. every 3 seconds I would like to see 3 threads of each for arguments sake.
Your tasks are probably too short for the fixed rate. Try with long tasks that exceed 3 seconds. You should see some different thread names in the output.
That is correct yes, but the problem is not that I am not seeing the thread overlapping, I have tested that, the problem is that I need the thread to be executed 3 times every three seconds. So after 2 executions I need to see 6 outputs for each task. currently it is only executing once and then waiting for the next run
0

Update: ok so based on your comments you need the following:

public class ServiceOne {
    @Async
    public void bgTask() {
        System.out.println(Thread.currentThread().getName());
    }
}

public class ServiceTwo {
    @Autowired
    ServiceOne serviceOne;

    @Scheduled(fixedRate = 3000, initialDelay = 5000)
    public void scheduledRunner() {
        int i = 3;
        while (i-- >0 ) {
            serviceOne.bgTask();
        }
    }
}

This way the scheduled method will be executed every three seconds and it will spawn three parallel background tasks. The inject thingie is for the AOP to work with the default weaver which would ignore one of the annotations if methods are in the same class.

According to docs this is what's probably happening:

By default, will be searching for an associated scheduler definition: either a unique TaskScheduler bean in the context, or a TaskScheduler bean named "taskScheduler" otherwise; the same lookup will also be performed for a ScheduledExecutorService bean. If neither of the two is resolvable, a local single-threaded default scheduler will be created and used within the registrar.

I think configuring a ScheduledTaskRegistrar might help:

public class SchedulerConfig implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(4); // Number of simultaneously running @Scheduled functions
        taskScheduler.initialize();
        taskRegistrar.setTaskScheduler(taskScheduler);
    }

2 Comments

Thanks, I have added this in, but I am getting the same result. Also I removed the TaskScheduler implementations I had in the application class with no change in the output
for all the copy-paste guys: don't forget to add @EnableScheduling

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.