ScheduledExecutor Service 사용 노트

그림으로 비교하면 이런 느낌이에요.



schedule() - 지정된 시간을 기다린 후 처리

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Main {

    public static void main(String[] args) throws Exception {
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

        service.schedule(() -> {
            System.out.println("end!!");
            service.shutdown();
            System.exit(0);
        }, 1, TimeUnit.SECONDS);

        int count = 0;
        while (true) {
            Thread.sleep(100);
            System.out.println((++count) * 100 + " ms");
        }
    }
}
실행 결과
100 ms
200 ms
300 ms
400 ms
500 ms
600 ms
700 ms
800 ms
900 ms
1000 ms
end!!

scheduleAtFixedRate() - 일정 시간마다 처리

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {
    public static void main(String... args) throws Exception {
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

        AtomicInteger number = new AtomicInteger(0);
        service.scheduleAtFixedRate(() -> {
            int n = number.getAndIncrement();
            System.out.println("begin(" + n + ")");
            sleep(Math.max(1, 3-n));
            System.out.println("end(" + n + ")");
        }, 2, 2, TimeUnit.SECONDS);

        int count = 0;
        while (true) {
            TimeUnit.SECONDS.sleep(1);
            System.out.println((++count) + " s");
        }
    }

    private static void sleep(long seconds) {
        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch (InterruptedException  e) {}
    }
}
  • 첫 번째 매개 변수의 처리 시간은 3초→2초→1초→1초→1초...축소 조정
  • 실행 결과
    1 s
    begin(0)
    2 s
    3 s
    4 s
    end(0)
    begin(1) ←直前の処理が終了するまで待機させられている
    5 s
    6 s
    end(1)
    begin(2)
    7 s
    end(2)
    begin(3)
    8 s
    end(3)
    9 s
    begin(4)
    10 s
    end(4)
    11 s
    begin(5)
    12 s
    end(5)
    13 s
    begin(6)
    14 s
    end(6)
    15 s
    
  • 두 번째 파라미터는 첫 번째 대기 시간입니다.
  • 세 번째 파라미터는 두 번째 이후의 대기 시간이다.

  • 첫 번째 파라미터의 처리가 완료되지 않아도 대기 시간이 지나면 gan-gan 처리라고 부른다.(2020년 3월 11일, 논평 지적 및 수정)
  • 세 번째 파라미터에 지정된 간격으로 첫 번째 파라미터에 대한 처리를 실행합니다
  • 단, 첫 번째 파라미터의 처리 시간이 세 번째 파라미터가 지정한 시간보다 길면 다음 처리를 이전 처리가 끝날 때까지 기다린다
  • 즉, 첫 번째 파라미터의 처리를 병행하지 않는 것이다
  • 보류 중인 처리는 이전 처리가 끝난 후 즉시 실행
  • scheduleWithFixedDelay() - 중복 처리가 완료될 때까지 일정 시간 기다림

    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    public class Main {
    
        private static int n = 0;
    
        public static void main(String[] args) throws Exception {
            ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
    
            service.scheduleWithFixedDelay(() -> {
                System.out.println("begin(" + n + ")");
                sleep(1000);
                System.out.println("end(" + n + ")");
                n++;
            }, 2, 1, TimeUnit.SECONDS);
    
            int count = 0;
            while (true) {
                sleep(1000);
                System.out.println((++count) + " s");
            }
        }
    
        private static void sleep(long ms) {
            try {
                Thread.sleep(ms);
            } catch (InterruptedException e) {}
        }
    }
    
    실행 결과
    1 s
    2 s
    begin(0)
    3 s
    end(0)
    4 s
    begin(1)
    5 s
    end(1)
    6 s
    begin(2)
    7 s
    end(2)
    8 s
    begin(3)
    9 s
    end(3)
    10 s
    
  • 두 번째 파라미터는 첫 번째 대기 시간입니다.
  • 첫 번째 파라미터의 처리가 완료되기를 기다린 후 세 번째 파라미터가 지정한 시간을 기다린 후 다음 처리를 실행
  • 참고 자료

  • ScheduledExecutorService (Java Platform SE 8 )
  • 좋은 웹페이지 즐겨찾기