복붙노트

[SPRING] 스프링 스케줄링 작업 - 한 번만 실행

SPRING

스프링 스케줄링 작업 - 한 번만 실행

정확하게 지정된 시간에 한 번만 Spring 서비스 메소드를 스케줄 할 수 있습니까? 예를 들어, 현재 시간은 오후 2시이지만 작업 버튼을 누르면 내 서비스 방법이 오후 8시에 시작됩니다. 저는 @Scheduled 어노테이션에 익숙하며 주기적으로 실행되지 않는 cron 표현식을 작성하는 방법을 모르겠습니다. 이 @Scheduled (cron = "0 0 20 * *?")는 매일 오후 8시에 발생합니다. 어떤 제안?

해결법

  1. ==============================

    1.Spring의 TaskScheduler 구현 중 하나를 사용할 수 있습니다. 아래 예제에서는 너무 많은 구성 (단일 스레드 스케줄 된 실행 프로그램을 래핑하는 ConcurrentTaskScheduler)이 필요하지 않은 예제를 제공했습니다.

    Spring의 TaskScheduler 구현 중 하나를 사용할 수 있습니다. 아래 예제에서는 너무 많은 구성 (단일 스레드 스케줄 된 실행 프로그램을 래핑하는 ConcurrentTaskScheduler)이 필요하지 않은 예제를 제공했습니다.

    작업 실행 및 스케줄링에 대해 자세히 읽어보십시오.

    간단한 작업 예제 :

    private TaskScheduler scheduler;
    
    Runnable exampleRunnable = new Runnable(){
        @Override
        public void run() {
            System.out.println("Works");
        }
    };
    
    @Async
    public void executeTaskT() {
        ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();
        scheduler = new ConcurrentTaskScheduler(localExecutor);
    
        scheduler.schedule(exampleRunnable,
                new Date(1432152000000L));//today at 8 pm UTC - replace it with any timestamp in miliseconds to text
    }
    
    ...
    
    executeTaskT() //call it somewhere after the spring application has been configured
    

    노트 :

    업데이트 - 예약 된 작업 취소

    TaskScheduler의 schedule 메서드는 취소 할 수있는 지연된 결과 보유 작업 인 ScheduledFuture를 반환합니다.

    따라서 취소하려면 예약 된 작업을 처리해야합니다 (예 : ScheduledFuture 반환 객체 유지).

    위의 코드를 변경하여 작업 취소하기 :

  2. ==============================

    2.모든 메소드 호출시 ScheduledExecutorService 및 ConcurrentTaskScheduler를 작성하지 않으려면 서비스 생성시 TaskScheduler를 초기화하는 것이 편리합니다.

    모든 메소드 호출시 ScheduledExecutorService 및 ConcurrentTaskScheduler를 작성하지 않으려면 서비스 생성시 TaskScheduler를 초기화하는 것이 편리합니다.

    private final TaskScheduler taskScheduler = 
                  new ConcurrentTaskScheduler(Executors.newScheduledThreadPool(10));
    

    @Async는 작업을 예약하고 메서드에서 종료 할 때 의미가 없습니다.

  3. ==============================

    3.PeriodicTrigger를 다음과 같이 확장 할 수 있습니다. lastCompletionTime을 확인합니다. 이전에 작업이 실행 된 적이없는 경우 null이됩니다. 주어진 시간에 한 번만 작업을 실행하려면이 변형을 시도 할 수 있습니다.

    PeriodicTrigger를 다음과 같이 확장 할 수 있습니다. lastCompletionTime을 확인합니다. 이전에 작업이 실행 된 적이없는 경우 null이됩니다. 주어진 시간에 한 번만 작업을 실행하려면이 변형을 시도 할 수 있습니다.

    class RunOnceTrigger extends PeriodicTrigger {
        public RunOnceTrigger(long period) {
            super(period);
            setInitialDelay(period);
        }
    
        @Override
        public Date nextExecutionTime(TriggerContext triggerContext) {
            if(triggerContext.lastCompletionTime() == null) {   // hasn't executed yet
                return super.nextExecutionTime(triggerContext);
            }
            return null;
        }
    }
    
  4. from https://stackoverflow.com/questions/30347233/spring-scheduling-task-run-only-once by cc-by-sa and MIT license