[컴][Java] Java Timer - fixed rate and fixed delay

java timer / scheduleAtFixedRate / fixed rate


여기서 설명하는 내용의 원본은 ref.2 를 보자.


Fixed Delay "고정된 지연"


Timer 에서 모든 TimerTask 가 하나의 thread 를 사용한다. 그래서 만약 하나의 task 가 thread 를 오래 잡고 있으면, 다른 task 들은 그 task 가 끝나기를 기다려야 한다.

t.schedule(new Ping("Fixed delay"), 0, 1000);
t.schedule(new Ping("Fixed rate"), 0, 2000);

위와 같은 경우가 있다고 하자. 위의 경우에 정상적으로 의도된 결과는 아래와 같을 것이다.(전체 소스는 ref. 1 을 참고하자.)

Fixed delay Ping at Wed Jan 29 10:16:46 KST 2014
Fixed rate Ping at Wed Jan 29 10:16:46 KST 2014
Fixed delay Ping at Wed Jan 29 10:16:47 KST 2014
Fixed delay Ping at Wed Jan 29 10:16:48 KST 2014
Fixed rate Ping at Wed Jan 29 10:16:48 KST 2014
Fixed delay Ping at Wed Jan 29 10:16:49 KST 2014
Fixed delay Ping at Wed Jan 29 10:16:50 KST 2014
Fixed rate Ping at Wed Jan 29 10:16:50 KST 2014
Fixed delay Ping at Wed Jan 29 10:16:51 KST 2014
Fixed delay Ping at Wed Jan 29 10:16:52 KST 2014
Fixed rate Ping at Wed Jan 29 10:16:52 KST 2014
Fixed delay Ping at Wed Jan 29 10:16:53 KST 2014

그런데 만약 2초마다 작동을 하는 task 의 작업을 마치는데 2초가 넘게 걸린다고 한다면, 아래와 같은 결과가 나온다.

Fixed delay Ping at Wed Jan 29 10:22:12 KST 2014
Fixed delay Ping at Wed Jan 29 10:22:13 KST 2014
Fixed rate Ping  at Wed Jan 29 10:22:19 KST 2014
Fixed delay Ping at Wed Jan 29 10:22:19 KST 2014
Fixed delay Ping at Wed Jan 29 10:22:20 KST 2014

매 1초 마다 정상적으로 찍히던 "Fixed delay" 도 찍지 못하고 있다. 이게 위에서 얘기한 모든 TimerTask 가 하나의 thread 를 사용하기 때문이다. 그래서 하나의 TimerTask 가 끝나기를 기다리느라 다른 task 가 수행되지 못하였다.

그리고 Fixed rate 가 끝나자 마자 다시 정상적으로 찍히기 시작한다. 잠시 정체가 되었음에도 그 정체된 시간에 관계 없이 일정한 delay 를 유지하고 있다. 이것을 "Fixed delay" 라 한다.

API 문서(ref. 4)의 설명이 도움이 된다.
schedule(TimerTask task, long delay, long period)
> Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay.

Fixed rate


scheduleAtFixedRate() 을 보자. 이녀석은 비율("일정 시간동안에 task 의 양") 을 맞추려고 노력한다. 아래 같은 code 가 있으면

t.scheduleAtFixedRate(new Ping("Fixed rate"), 0, 1000);

1000ms 당 1개의 Task 가 있도록 최대한 맞추려고 한다. 그래서 아래 처럼 시간이 오래걸려 시간이 정체되는 task 가 발생하게 되면, 그 task 가 끝나고 나서 그동안 수행하지 못했던 task 를 여러개를 거의 같은 시간에 실행시키게 된다. 그래서 최대한 비율의 평균치가 잘 나오도록 하는 것이다.

t.scheduleAtFixedRate(new Ping("Fixed rate"), 0, 1000);
t.schedule(new PainstakinglySlowTask(), 2000);

Fixed rate Ping at Thu May 18 15:48:34 EDT 2000
Fixed rate Ping at Thu May 18 15:48:35 EDT 2000
Painstaking task ran at Thu May 18 15:48:41 EDT 2000
Fixed rate Ping at Thu May 18 15:48:41 EDT 2000
Fixed rate Ping at Thu May 18 15:48:41 EDT 2000
Fixed rate Ping at Thu May 18 15:48:41 EDT 2000
Fixed rate Ping at Thu May 18 15:48:41 EDT 2000
Fixed rate Ping at Thu May 18 15:48:41 EDT 2000
Fixed rate Ping at Thu May 18 15:48:41 EDT 2000
Fixed rate Ping at Thu May 18 15:48:42 EDT 2000
Fixed rate Ping at Thu May 18 15:48:43 EDT 2000




Reference

  1. http://blog.naver.com/PostView.nhn?blogId=saojung50&logNo=120050451007&categoryNo=23&viewDate=&currentPage=1&listtype=0
  2. 원문 : http://web.mit.edu/java/JDCNewsletter/JDC-TECH5-00b
  3. http://stackoverflow.com/questions/4544197/how-do-i-schedule-a-task-to-run-at-periodic-intervals
  4. http://docs.oracle.com/javase/7/docs/api/java/util/Timer.html

댓글 없음:

댓글 쓰기