簡體   English   中英

如何在 Spring 中運行相同的@Scheduled 方法以多線程啟動

[英]How to run the same @Scheduled method in Spring Boot in multiple threads

我目前在我的 Spring Boot 應用程序中有一個 @Scheduled 方法

   @Async
    @Scheduled(fixedDelay = 2000, initialDelay = 1000)
    public void taskA() throws InterruptedException {
        System.out.println("A - " + Thread.currentThread().getName());
    }

我的 Spring 應用文件如下:@SpringBootApplication

@EnableAsync
@EnableScheduling
public class SpringScheduleApplication {

    public static void main(String[] args) {

        SpringApplication.run(SpringScheduleApplication.class, args);
    }


}

我還設置了一個配置 class 以建立線程池以允許並行作業

@Configuration
@EnableScheduling
public class SchedulingConfig implements SchedulingConfigurer {
    public static final int NUM_PROCESSING_WORKERS = 10;
    @Override
    public void configureTasks(
            ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }

    @Bean
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(NUM_PROCESSING_WORKERS);
    }
}

當我運行調度程序時,我可以清楚地看到作業正在多個線程池中進行。

A - pool-1-thread-7
A - pool-1-thread-3
A - pool-1-thread-9
....

好的.....所以這是我的問題

我想做的是創建taskA的多個實例並讓它在 N 個線程中運行。

我知道我可以使用@Scheduled注釋創建 N 數量的方法來執行相同的邏輯,但這不是一個可接受的解決方案。 這似乎非常多余並且看起來很糟糕,並且如果我向池中添加另一個線程,則不想復制粘貼。 我希望能夠這樣說:

for(int i = 0; i < SchedulingConfig.NUM_PROCESSING_WORKERS; i++){
  taskA(); // I just want N amount of this tasks existing in parallel.
}

我不能使用 Quartz Scheduler 之類的東西,因為我希望能夠在我的項目中繼續使用@Autowired (我可以讓這種行為在 Quartz 中工作,但設置 @Autowired 很痛苦,我想使用 Spring Schedule盡可能多的注釋)

你已經自己寫了答案。 您已經有了要使用的for循環。 @Scheduled放在帶有for 循環的方法上,該循環調用外部class 中的taskA方法,並且具有@Async注釋。


@Autowired
private External external

@Scheduled
public void scheduler() {
  for(int i = 0; i < SchedulingConfig.NUM_PROCESSING_WORKERS; i++){
    external.taskA(); // I just want N amount of this tasks existing in parallel.
  }
}
public class External {


  @Async
  public void taskA() { ... }

}

另一種解決方案是將AsyncTaskExecutor注入您的 class 執行調度並調用submit以執行任務。

@Autowired
private AsyncTaskExecutor taskExecutor;

@Scheduled
public void scheduler() {
  for(int i = 0; i < SchedulingConfig.NUM_PROCESSING_WORKERS; i++){
    taskExecutor.submit( () -> taskA());  
  }
}

這樣做的好處是它更明確,並且您的taskA方法可以在同一個 class 中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM