java - minutes - Ejecución paralela de Spring @Scheduler
spring boot scheduled task example (1)
Tengo las siguientes 3 clases:
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);
}
}
}
Componente B
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);
}
}
}
Mi aplicación
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);
}
}
Cuando lo ejecuto, obtengo el siguiente resultado:
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
...
Necesito que los 2 métodos programados se ejecuten en paralelo, lo que claramente no es el cae de acuerdo con la salida que obtengo. Leí que debería ser posible proporcionar la anotación @Schedule con un TaskExecutor personalizado, con el cual debería ser posible definir cuántos hilos queremos ...
¿Estoy en lo cierto? No puedo encontrar cómo proporcionar esta información.
La documentación establece claramente que:
De forma predeterminada, buscará una definición de planificador asociada: un bean
TaskScheduler
único en el contexto, o un beanTaskScheduler
llamado "taskScheduler"; la misma búsqueda también se realizará para un beanScheduledExecutorService
. Si ninguno de los dos se puede resolver, se creará un planificador predeterminado local de un único subproceso y se utilizará dentro del registrador.Cuando se desea más control, una clase @Configuration puede implementar SchedulingConfigurer. Esto permite el acceso a la instancia subyacente de ScheduledTaskRegistrar. Por ejemplo, el siguiente ejemplo muestra cómo personalizar el Ejecutor utilizado para ejecutar tareas programadas:
@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);
}
}