Reputation: 1170
I have the following 3 classes:
ComponantA
package mytest.spring.test.spring;
import org.apache.log4j.Logger;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ComponentA {
Logger log = Logger.getLogger(ComponentB.class);
@Scheduled(fixedRate=2000)
public void sayHello() {
for(int i=1 ; i<=5 ; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
log.info("Hello from ComponentA " + i);
}
}
}
ComponentB
package mytest.spring.test.spring;
import org.apache.log4j.Logger;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ComponentB {
Logger log = Logger.getLogger(ComponentB.class);
@Scheduled(fixedRate=2000)
public void sayHello() {
for(int i=1 ; i<=3 ; i++) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
log.info("Hello from ComponentB " + i);
}
}
}
MyApplication
package mytest.spring.test.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
When I execute it, I'm getting the following output:
Hello from ComponentA 1
Hello from ComponentA 2
Hello from ComponentA 3
Hello from ComponentA 4
Hello from ComponentA 5
Hello from ComponentB 1
Hello from ComponentB 2
Hello from ComponentB 3
Hello from ComponentA 1
Hello from ComponentA 2
Hello from ComponentA 3
Hello from ComponentA 4
Hello from ComponentA 5
Hello from ComponentB 1
Hello from ComponentB 2
Hello from ComponentB 3
...
I need the 2 Scheduled methods to run in parallel, which is clearly not the cae according to the output I'm getting. I read that it should be possible to provide the @Schedule annotation with a custom TaskExecutor, with which it should be possible to define how many thread we want ...
Am I right ? I can't find how to provide this information.
Upvotes: 23
Views: 19845
Reputation: 9459
Configure this property in application.properties
:
spring.task.scheduling.pool.size=2
Value means the number of threads which may be used by scheduled tasks. Default pool size is 1 and this setting is available since SpringBoot 2.1.0
The same task will be executed in serialized when the trigger period is shorter than the execution duration. Different tasks will run in parallel with a maximum of threads you set.
Upvotes: 4
Reputation: 41608
The documentation clearly states that:
By default, will be searching for an associated scheduler definition: either a unique
TaskScheduler
bean in the context, or aTaskScheduler
bean named "taskScheduler" otherwise; the same lookup will also be performed for aScheduledExecutorService
bean. If neither of the two is resolvable, a local single-threaded default scheduler will be created and used within the registrar.When more control is desired, a @Configuration class may implement SchedulingConfigurer. This allows access to the underlying ScheduledTaskRegistrar instance. For example, the following example demonstrates how to customize the Executor used to execute scheduled tasks:
@Configuration @EnableScheduling public class AppConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setScheduler(taskExecutor()); } @Bean(destroyMethod="shutdown") public Executor taskExecutor() { return Executors.newScheduledThreadPool(100); } }
Upvotes: 43