개발/자바

ScheduledThreadPool 샘플(매일 오전 1시 실행)

피터JK 2025. 2. 17. 15:35
728x90

아래는 매일 오전 1시에 실행되는 ScheduledThreadPool을 만들고, 애플리케이션 종료 시 안전하게 종료하는 코드입니다.


📌 전체 코드

import java.util.concurrent.*;

public class ScheduledTaskExample {
    public static void main(String[] args) {
        // 1개 쓰레드로 구성된 ScheduledThreadPool 생성
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        // 🕐 매일 오전 1시에 실행되는 작업 스케줄링
        Runnable task = () -> System.out.println("매일 오전 1시에 실행: " + java.time.LocalDateTime.now());

        // 현재 시간 기준으로 다음 오전 1시까지 대기 시간 계산
        long initialDelay = computeInitialDelay(1, 0);  // 오전 1시
        long period = TimeUnit.DAYS.toSeconds(1); // 1일(24시간) 주기

        // 스케줄러에 작업 등록
        scheduler.scheduleAtFixedRate(task, initialDelay, period, TimeUnit.SECONDS);

        // 🛑 애플리케이션 종료 시 스케줄러 안전 종료
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("애플리케이션 종료 - 스케줄러 종료 중...");
            scheduler.shutdown();
            try {
                if (!scheduler.awaitTermination(10, TimeUnit.SECONDS)) {
                    scheduler.shutdownNow();
                }
            } catch (InterruptedException e) {
                scheduler.shutdownNow();
            }
            System.out.println("스케줄러 종료 완료.");
        }));
    }

    // 현재 시간 기준으로 다음 오전 1시까지 대기 시간 계산
    private static long computeInitialDelay(int targetHour, int targetMinute) {
        java.time.LocalDateTime now = java.time.LocalDateTime.now();
        java.time.LocalDateTime nextRun = now.withHour(targetHour).withMinute(targetMinute).withSecond(0);

        if (now.isAfter(nextRun)) { // 이미 오늘 오전 1시가 지났으면 내일 실행
            nextRun = nextRun.plusDays(1);
        }

        return java.time.Duration.between(now, nextRun).getSeconds();
    }
}

🚀 코드 설명

  1. Executors.newScheduledThreadPool(1)
    → 단일 쓰레드로 동작하는 ScheduledThreadPool 생성
  2. computeInitialDelay(1, 0)
    → 현재 시간 기준으로 다음 오전 1시까지의 대기 시간 계산
  3. scheduler.scheduleAtFixedRate(task, initialDelay, 86400, TimeUnit.SECONDS)
    매일 오전 1시에 실행되도록 설정
  4. Runtime.getRuntime().addShutdownHook(...)
    애플리케이션 종료 시 스케줄러를 안전하게 종료

✅ 실행 결과 (예시)

매일 오전 1시에 실행: 2025-02-18T01:00:00
(다음날)
매일 오전 1시에 실행: 2025-02-19T01:00:00
(계속 반복)
...
(애플리케이션 종료 시)
애플리케이션 종료 - 스케줄러 종료 중...
스케줄러 종료 완료.

이제 매일 오전 1시에 실행되면서, 애플리케이션 종료 시 안전하게 종료됩니다! 

728x90

'개발 > 자바' 카테고리의 다른 글

java : import static  (0) 2025.02.18
try-with-resources란?  (1) 2025.02.17
Thread ExecutorService API  (0) 2025.02.17
Thread 설정 및 주요 메서드  (0) 2025.02.17
Thread 클래스 상속 vs Runnable 인터페이스 구현  (0) 2025.02.17