ScheduledExecutorService — 지연·주기 실행을 지원하는 ExecutorService

ScheduledExecutorService — 지연·주기 실행을 지원하는 ExecutorService

ScheduledExecutorService는 주어진 지연 후 실행하거나 주기적으로 실행하도록 커맨드를 스케줄할 수 있는 ExecutorService예요. 예약된 작업을 관리·취소하려면 ScheduledFuture를 돌려받아요.

출처: Java API Reference

본문

개념 이해하기

ScheduledExecutorService는 주어진 지연 후 실행하거나 주기적으로 실행하도록 커맨드를 스케줄할 수 있는 ExecutorService예요.

public interface ScheduledExecutorService
extends ExecutorService
  • schedule 메서드는 다양한 지연으로 태스크를 만들고, 취소·실행 확인에 쓰는 태스크 객체를 반환해요.
  • scheduleAtFixedRatescheduleWithFixedDelay취소될 때까지 주기적으로 실행되는 태스크를 만들고 실행해요.
  • execute/submit으로 제출된 커맨드는 요청 지연 0으로 스케줄돼요. schedule 메서드에서는 0과 음수 지연(주기는 아님)도 허용돼 즉시 실행 요청으로 취급돼요.
  • 모든 schedule 메서드는 상대적 지연·주기를 인자로 받아요(절대 시간/날짜 아님). Date를 상대 시간으로 바꾸려면 schedule(task, date.getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS)을 써요. 단 절대 시각은 네트워크 시간 동기화·클록 드리프트로 인해 정확히 일치하지 않을 수 있어요.

대표 구현체는 ScheduledThreadPoolExecutor예요. Executors가 팩토리 메서드를 제공해요.

활용 예 — 10초마다 비프, 1시간 후 중지

import static java.util.concurrent.TimeUnit.*;
class BeeperControl {
    private final ScheduledExecutorService scheduler =
        Executors.newScheduledThreadPool(1);

    public void beepForAnHour() {
        Runnable beeper = () -> System.out.println("beep");
        ScheduledFuture<?> beeperHandle =
            scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
        Runnable canceller = () -> beeperHandle.cancel(false);
        scheduler.schedule(canceller, 1, HOURS);
    }
}

schedule 메서드

ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) — 주어진 지연 후 활성화되는 일회성(one-shot) 태스크를 제출해요. 완료 시 get()null 반환.

  • command — 실행할 태스크, delay — 실행까지 지연 시간, unit — 지연 단위
  • RejectedExecutionException, NullPointerException

<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) — 지연 후 활성화되는 값을 반환하는 일회성 태스크를 제출해요.

  • RejectedExecutionException, NullPointerException

주기 스케줄

ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)initialDelay 후 처음 활성화되고, 그 후 period마다 실행되는 주기적 액션을 제출해요. 실행은 initialDelay, initialDelay + period, initialDelay + 2*period 순으로 시작돼요.

실행 시퀀스는 다음 중 하나가 발생할 때까지 무한히 계속돼요: 태스크가 반환된 future로 명시 취소, executor 종료(태스크 취소로 이어짐), 또는 태스크 실행이 예외를 던짐(반환 future의 get이 그 예외를 cause로 가진 ExecutionException을 던짐). 이후 실행은 억제돼요.

한 번의 실행이 period보다 오래 걸리면 후속 실행이 늦게 시작될 수 있지만 동시에 실행되지는 않아요.

  • period — 연속 실행 사이의 주기
  • RejectedExecutionException, NullPointerException, IllegalArgumentException (period <= 0)

ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)initialDelay 후 처음 활성화되고, 한 실행의 종료와 다음 실행의 시작 사이에 주어진 delay 가 있도록 주기 실행되는 액션을 제출해요. (scheduleAtFixedRate와 달리 고정된 시작 간격이 아니라 고정된 지연)

  • delay — 한 실행 종료와 다음 실행 시작 사이 지연. RejectedExecutionException, NullPointerException, IllegalArgumentException (delay <= 0)

더 알아보기 (Learn more)