[java] scheduleAtFixedRate 대 scheduleWithFixedDelay
ScheduledExecutorService의scheduleAtFixedRate
와 scheduleWithFixedDelay
메소드의 주요 차이점은 무엇입니까 ?
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
방법의 시계열을 시각화합니다 . 마지막 실행이 기간보다 오래 걸리면 다음 실행이 즉시 시작됩니다. 그렇지 않으면 일정 시간 후에 시작됩니다.
호출 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);
실행 만하면 차이를 알 수 있습니다. 감사합니다