[java] scheduleAtFixedRate 대 scheduleWithFixedDelay

ScheduledExecutorService의scheduleAtFixedRatescheduleWithFixedDelay메소드의 주요 차이점은 무엇입니까 ?

scheduler.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        System.out.println("scheduleAtFixedRate:    " + new Date());
    }
}, 1, 3L , SECONDS);

scheduler.scheduleWithFixedDelay(new Runnable() {
    @Override
    public void run() {
        System.out.println("scheduleWithFixedDelay: " + new Date());
    }
}, 1, 3L , SECONDS);

그들은 정확히 같은 시간에 인쇄하고 정확히 같은 간격으로 실행되는 것처럼 보입니다.



답변

메서드 Thread.sleep(1000);내 에서 호출을 추가해보세요 run()… 기본적으로 이전 실행이 종료되는 시점과 (논리적으로) 시작 되는 시점을 기준으로 일정을 예약하는 것의 차이 입니다.

예를 들어 1 시간에 한 번 고정 된 속도 로 알람이 울리도록 예약하고 알람이 울릴 때마다 10 분 정도 걸리는 커피를 마신다고 가정 해 보겠습니다 . 자정에 시작한다고 가정하면 다음과 같습니다.

00:00: Start making coffee
00:10: Finish making coffee
01:00: Start making coffee
01:10: Finish making coffee
02:00: Start making coffee
02:10: Finish making coffee

1 시간 의 고정 지연 으로 일정을 잡는 경우 다음을 수행 할 수 있습니다.

00:00: Start making coffee
00:10: Finish making coffee
01:10: Start making coffee
01:20: Finish making coffee
02:20: Start making coffee
02:30: Finish making coffee

원하는 것은 작업에 따라 다릅니다.


답변

호출 scheduleAtFixedRate방법의 시계열을 시각화합니다 . 마지막 실행이 기간보다 오래 걸리면 다음 실행이 즉시 시작됩니다. 그렇지 않으면 일정 시간 후에 시작됩니다.

호출 scheduleAtFixedRate 메서드의 시계열

호출 scheduleWithFixedDelay방법의 시계열 . 다음 실행은 실행 시간에 관계없이 한 실행 종료와 다음 실행 시작 사이의 지연 시간 후에 시작됩니다.

호출 scheduleWithFixedDelay 메서드의 시계열

희망이 당신을 도울 수 있습니다


답변

scheduleAtFixedRate()메서드는 새 작업을 만들고 이전 작업이 완료되었는지 여부에 관계없이 매 기간마다 실행자에게 제출합니다 .

반면에이 scheduleWithFixedDelay()메서드 는 이전 작업이 완료된 후 새 작업 만듭니다 .


답변

Java Doc을 읽으면 더 명확해질 것입니다.

ScheduledFuture scheduleAtFixedRate (Runnable command, long initialDelay, long period, TimeUnit unit)
지정된 초기 지연 후 먼저 활성화되고 이후에 지정된 기간으로 활성화되는 주기적 작업을 생성하고 실행합니다. 즉, initialDelay, initialDelay + period, initialDelay + 2 * period 등으로 실행이 시작됩니다.

ScheduledFuture scheduleWithFixedDelay (Runnable command, long initialDelay, long delay, TimeUnit unit)
지정된 초기 지연 후 먼저 활성화되고 이후에 한 실행의 종료와 다음 실행의 시작 사이에 지정된 지연으로 활성화되는 주기적 작업을 생성하고 실행합니다.


답변

첫 번째 스레드가 너무 오래 걸리고 주어진 기간 내에 종료되지 않은 경우 scheduleAtFixedRate에 한 가지 캐치가 있으며 첫 번째 작업이 완료되면 두 번째 연속 스레드가 시작되지 않고 첫 번째 스레드가 작업 및 gievn 기간을 완료하는 동안 즉시 시작되지 않습니다. 경과되었습니다. JVM은 다음 작업이 실행될시기를 결정합니다.

나는 이것이 당신이 방법을 선택하는 데 도움이 될 것이라고 생각합니다.


답변

간단한 프로그램을 작성해 보겠습니다.

import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit

var time = 0L
var start = System.currentTimeMillis()
val executor = Executors.newScheduledThreadPool(1)
executor.scheduleWithFixedDelay({
    if (time >= 12_000L) {
        executor.shutdown()
    } else {
        Thread.sleep(2000L)
        val now = System.currentTimeMillis()
        time += now - start
        System.out.println("Total $time delay ${now - start}\n")
        start = now
    }
}, 0L, 1000L, TimeUnit.MILLISECONDS)

결과를 확인하십시오.

| scheduleWithFixedDelay |   scheduleAtFixedRate  |
|:----------------------:|:----------------------:|
| Total 2001 delay 2001  | Total 2003 delay 2003  |
| Total 5002 delay 3001  | Total 4004 delay 2001  |
| Total 8003 delay 3001  | Total 6004 delay 2000  |
| Total 11003 delay 3000 | Total 8004 delay 2000  |
| Total 14003 delay 3000 | Total 10005 delay 2001 |
|          ---           | Total 12005 delay 2000 |

실행 시간이 기다리는 것보다 큽니다.

scheduleWithFixedDelay 는 지연을 유지합니다.
scheduleAtFixedRate 는 지연을 제거합니다.


답변

scheduledExecutorService.scheduleAtFixedRate(() -> {
        System.out.println("runnable start"); try { Thread.sleep(5000);  System.out.println("runnable end");} catch
     (InterruptedException e) { // TODO Auto-generated catch block
      e.printStackTrace(); }}, 2, 7, TimeUnit.SECONDS);



     scheduledExecutorService.scheduleWithFixedDelay(() -> {
     System.out.println("runnable start"); try { Thread.sleep(5000); System.out.println("runnable end");} catch
     (InterruptedException e) { // TODO Auto-generated catch block
     e.printStackTrace(); } }, 2, 7, TimeUnit.SECONDS);

실행 만하면 차이를 알 수 있습니다. 감사합니다