자체 스레드에서 각 Spring Scheduler 실행
여러 개의 구성 요소가 있습니다.@Scheduled
주석, 그리고 Spring은 같은 시간에 실행되도록 예약되어 있더라도 한 번에 하나만 시작됩니다.
저의 사용 사례는 다음과 같습니다.각 @Scheduled 주석을 각 스레드에 한 번만 실행하도록 합니다.
두 개의 스케줄러가 있는 이 유사 코드를 고려할 때:
@Scheduled(cron = "0 * * * * *") //run every minute
public void methodA() {
log.info("Running method A");
executeLongRunningJob("Finished method A");
}
@Scheduled(cron = "0 * * * * *") //run every minute
public void methodB() {
log.info("Running method B");
executeLongRunningJob("Finished method B");
}
private void executeLongRunningJob(String msg) {
Thread.sleep(70 seconds);
System.out.println(msg);
}
작업은 스케줄러가 실행되도록 예약된 시간보다 더 오래 걸립니다.이것은 매우 중요합니다.실행이 완료되기 전에 스케줄러를 다시 시작하지 않습니다.
이 코드를 즉시 실행하면 다음과 같은 출력이 나타납니다.
Running method A
Finished method A
Running method B
Finished method B
Running method A
Finished method A
Running method B
Finished method B
... and so on
따라서 두 스케줄러를 하나의 스레드에서 실행하는 것은 분명합니다.
제가.@Async
값비싼 메소드를 사용하면 새 스케줄러가 시작되기 전에 값비싼 메소드가 완료되지 않는 것을 제외하고는 거의 정확한 동작을 수행할 수 있습니다.
Running method A
Running method B
Running method A
Running method B
Finished method A
Finished method B
... and so on
제가 원하는 것은 다음과 같습니다.
Running method A
Running method B
Finished method A
Finished method B
Running method A
Running method B
Finished method A
Finished method B
... and so on
어떻게 하면 이 일을 해낼 수 있을까요?각 스케줄러를 동시에 실행하되 완료될 때까지 기다렸다가 다시 실행하도록 허용합니다.두 개 이상의 스케줄러가 동일한 시간과 때로는 다른 시간에 실행되고 있습니다.
맞습니다. 기본적으로 스케줄러는 크기가 1인 스레드 풀을 사용하므로 모든 작업이 순차적으로 처리됩니다.원하는 풀 크기의 빈을 구성하여 사용할 수 있습니다.다음 예를 고려합니다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.Date;
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public TaskScheduler taskScheduler() {
final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(10);
return scheduler;
}
@Scheduled(fixedDelay = 2 * 1000L, initialDelay = 3 * 1000L)
public void scheduled1() throws InterruptedException {
System.out.println(new Date() + " " + Thread.currentThread().getName() + ": scheduled1");
Thread.sleep(1000);
}
@Scheduled(fixedDelay = 3 * 1000L, initialDelay = 3 * 1000L)
public void scheduled2() throws InterruptedException {
System.out.println(new Date() + " " + Thread.currentThread().getName() + ": scheduled2");
Thread.sleep(1000);
}
}
예약된 모든 작업을 별도의 스레드에서 실행합니다. 예:
Tue Jul 18 20:21:50 CEST 2017 taskScheduler-1: scheduled2
Tue Jul 18 20:21:50 CEST 2017 taskScheduler-2: scheduled1
Tue Jul 18 20:21:53 CEST 2017 taskScheduler-1: scheduled1
Tue Jul 18 20:21:54 CEST 2017 taskScheduler-3: scheduled2
Tue Jul 18 20:21:56 CEST 2017 taskScheduler-2: scheduled1
Tue Jul 18 20:21:58 CEST 2017 taskScheduler-4: scheduled2
Tue Jul 18 20:21:59 CEST 2017 taskScheduler-1: scheduled1
언급URL : https://stackoverflow.com/questions/45173390/running-each-spring-scheduler-in-its-own-thread
'programing' 카테고리의 다른 글
mysqdump를 사용하여 Galera 클러스터 백업 (0) | 2023.08.26 |
---|---|
JSF f:event preRenderView는 f:ajax 호출 및 부분 렌더링에 의해 트리거됩니다. 다른 것이 있습니까? (0) | 2023.08.26 |
virtualenwrapper를 사용하여 환경 이름 변경 (0) | 2023.08.26 |
CSS로 특정 텍스트를 선택할 수 없도록 만드는 방법 (0) | 2023.08.26 |
C#이 있는 압축/압축 해제 문자열 (0) | 2023.08.26 |