Timer 클래스를 이용한 작업 스케쥴링

Java 2001.04.16 12:42

JDK1.3에 새롭게 추가된 java.util.Timer 클래스를 사용하여 이벤트의 실행을 제어하는 것에 대해서 알아본다.

java.util.Timer 클래스와 java.util.TimerTask 클래스

유닉스나 리눅스에서 특정 시간에 어떤 프로세스를 실행시키고자 할 경우에 많이 사용되는 것이 cron 명령어와 at 명령어이다. 이 두 명령어는 임시 파일을 주기적으로 삭제하거나 중요 데이터를 일정 주기로 백업하고자 할 때 많이 사용된다. 윈도우 2000 서버 역시 이와 비슷한 기능을 제공하고 있다. 하지만, 아쉽게도 JDK1.2 까지는 유닉스나 리눅스의 cron 이나 at 명령어와 비슷한 기능을 수행하기 위해서는 개발자가 직접 쓰레드를 이용하여 구현해주어야 했다.

하지만, JDK1.3에 새롭게 추가된 클래스인 java.util.Timer 클래스와 java.util.TimerTask 클래스를 사용하면 이런 기능을 매우 손쉽게 구현할 수 있게 된다. 이 글에서는 Timer 클래스와 TimerTask 클래스에 대해서 알아보고, 어떻게 사용될 수 있는 지 예를 통해 살펴보자.

java.util.Timer 클래스는 백그라운드에서 특정한 시간 또는 일정 시간을 주기로 반복적으로 특정 작업을 실행할 수 있도록 해 준다. Timer 클래스는 크게 다음과 같이 세 가지 종류의 메소드를 제공한다.
 
  • schedule
  • scheduleAtFixedRate
  • cancel
위에서 schedule() 메소드는 특정한 시간에 원하는 작업을 수행하고자 할 때 사용하는 메소드로 다음 표와 같이 4가지 형태가 존재한다.
 
void schedule(TimerTask task, Date time)
지정한 시간(time)에 지정한 작업(task)을 수행한다.
void schedule(TimerTask task, Date firstTime, long period)
지정한 시간(firstTime) 부터 일정 간격(period)으로 지정한 작업(task)을 수행한다.
void schedule(TimerTask task, long delay)
일정 시간(delay)이 지난 후에 지정한 작업(task)을 수행한다.
void schedule(TimerTask task, long delay, long period)
일정 시간(delay)이 지난 후에 일정 간격(period)으로 지정한 작업(task)을 수행한다.
schedule() 메소드 중에는 지정한 시간부터 작업을 수행하는 것이 두 개 존재한다. 이 두 메소드는 지정한 시간이 현재 시간보다 과거일 경우 바로 TimerTask 작업을 수행한다. 그리고 schedule() 메소드에서 일정 간격으로 작업을 수행하는 메소드가 있는데, 이들 메소드는 fixed-delay 방식으로 작업을 진행한다. fixed-delay 방식은 만약 선행 작업이 가비지 콜렉션이나 기타 다른 이유 때문에 지연될 경우 그 다음에 수행되는 작업의 시작이 그 시간만큼 지연된다. 따라서, schedule() 메소드는 일정 주기로 실행되는 작업들이 정확한 시간에 실행될 필요가 없는 경우에 알맞다.

정확하게 일정 시간 간격으로 작업을 실행하기 위해서는 scheduleAtFixedRate() 메소드를 사용해야 한다. scheduleAtFixedRate() 메소드는 fixed-rate 방식으로 작업을 진행한다. fixed-rate 방식은 선행 작업이 지연되는 여부에 상관없이 지정된 시간에 작업을 실행한다. 따라서, 정확하게 특정 시간 마다 실행해야 하는 작업의 경우에는 schedule() 메소드가 아닌 scheduleAtFixedRate() 메소드를 사용하는 것이 좋다. 다음 표는 scheduleAtFixedRate() 메소드를 정리한 것이다.
 
void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
지정한 시간(firstTime)부터 일정 간격(period)으로 지정한 작업(task)을 수행한다.
void scheduleAtFixedRate(TimerTask task, long delay, long period)
일정한 시간(delay)이 지난후에 일정 간격(period)으로 지정한 작업(task)을 수행한다.
Timer 클래스는 스케쥴을 중지할 수 있도록 cancel() 메소드를 제공한다. cancel() 메소드는 Timer를 중지시키며, 실행될 예정인 모든 작업을 취소한다. 하지만, 현재 실행되고 있는 TimerTask 작업에 대해서는 영향을 미치지는 않는다.

이제 TimerTask 클래스에 대해서 알아보자. TimerTask 클래스는 Timer 클래스가 수행할 작업을 나타낸다. TimerTask 클래스는 Runnable 인터페이스를 implements 하고 있으며, 그 외에 몇 가지 필요한 메소드를 정의하고 있다. 다음 표는 TimerTask 클래스가 제공하고 있는 메소드를 정리한 것이다.
 
boolean cancel()
이 TimerTask 작업을 취소한다.
abstract void run()
이 TimerTask가 실행할 작업
long scheduledExecutionTime()
가장 최근에 이 작업이 실행된 시간을 리턴한다.
TimerTask 클래스를 보면 추상 메소드인 run()이 있는데 개발자는 TimerTask 클래스를 상속받은 후에 run() 메소드를 알맞게 구현해주면 된다.

간단한 예제

간단하게 Timer 클래스를 사용하여 3초마다 문자열을 현재 시간을 출력해주는 프로그램을 작성해보자. 이 프로그램은 다음과 같다.
 
import java.util.Timer;
import java.util.TimerTask;
import java.util.Date;

public class PrintTimer {
   
   public static void main(String[] args) {
      ScheduledJob job = new ScheduledJob();
      Timer jobScheduler = new Timer();
      jobScheduler.scheduleAtFixedRate(job, 1000, 3000);
      try {
         Thread.sleep(20000);
      } catch(InterruptedException ex) {
         //
      }
      jobScheduler.cancel();
   }
}

class ScheduledJob extends TimerTask {
   
   public void run() {
      System.out.println(new Date());
   }
}

PrintTimer는 main() 메소드에서 Timer 객체를 생성한 후, scheduleAtFixedRate() 메소드를 사용하여 1초 후부터 3초 간격으로 ScheduledJob 클래스의 run() 메소드를 실행한다. PrintTimer 클래스를 실행해보면 다음과 같은 결과가 출력될 것이다.
 
Fri Apr 13 15:26:47 GMT+09:00 2001
Fri Apr 13 15:26:50 GMT+09:00 2001
Fri Apr 13 15:26:53 GMT+09:00 2001
Fri Apr 13 15:26:56 GMT+09:00 2001
Fri Apr 13 15:26:59 GMT+09:00 2001
...

Daemon Thread?

Timer 클래스의 기본 생성자(즉, 파라미터가 없는 생성자)를 사용하여 Timer 클래스를 생성할 경우 Timer 클래스와 관련된 작업을 실행할 때 사용되는 쓰레드는 데몬 쓰레드로 실행되지 않는다. 데몬 쓰레드로 실행되지 않는다는 것은 Timer 객체와 관련된 클래스가 종료되지 않는 한 어플리케이션의 실행이 끝나지 않는다는 것을 의미한다. 따라서 앞에 예제에서도 cancel() 메소드를 사용하여 강제적으로 Timer 클래스와 관련된 쓰레드의 실행을 종료했었다. 실제로 앞의 PrintTimer 예제에서 jobScheduler.cancel() 부분을 삭제한다면 어플리케이션은 종료하지 않고 계속해서 실행될 것이다.

하지만, 때때로 Timer 클래스와 관련된 쓰레드를 데몬 쓰레드로 실행하고 싶은 경우가 있다. 이런 경우를 위해 Timer 클래스는 데몬 쓰레드로 지정할 지의 여부를 입력받을 수 있는 생성자를 제공하고 있다. 이 생성자는 boolean 값을 갖는 한 개의 파라미터를 입력받는다. 이 때, boolean 값이 true이면 Timer 클래스와 관련된 쓰레드들은 데몬 쓰레드로 설정된다. 예를 들어, 다음의 NewPrintTimer 클래스를 살펴보자.
 
import java.util.Timer;
import java.util.TimerTask;
import java.util.Date;

public class NewPrintTimer {
   
   public static void main(String[] args) {
      NewScheduledJob job = new NewScheduledJob();
      Timer jobScheduler = new Timer(true);
      jobScheduler.scheduleAtFixedRate(job, 1000, 3000);
      try {
         Thread.sleep(20000);
      } catch(InterruptedException ex) {
         //
      }
      // cancel() 메소드를 호출하지 않는다.
   }
}

class NewScheduledJob extends TimerTask {
   
   public void run() {
      System.out.println(new Date());
   }
}

NewPrintTimer 클래스의 mani() 메소드를 살펴보면 Timer 클래스를 생성할 때 Timer(true) 생성자를 사용하여 Timer 객체와 관련된 쓰레드를 데몬으로 설정하고 있으며, Timer 클래스의 cancel() 메소드를 호출하지 않고 있다. main() 메소드의 실행이 끝나게 되면 Timer 클래스와 관련된 쓰레드는 모두 데몬 쓰레드이기 때문에 어플리케이션은 종료하게 된다. 실제로 NewPrintTimer를 실행해보면 이 사실을 확인할 수 있다.

결론

java.util.Timer 클래스와 java.util.TimerTask 클래스를 사용하여 반복적으로 또는 특정한 시간에 원하는 작업을 실행할 수 있게 되었다. JDK1.3 이전에는 이러한 기능을 언어 차원에서 지원하지 않았기 때문에 필요할 경우 개발자가 직접 구현을 해 주어야 했었지만, 이제는 매우 손쉽게 구현할 수 있게 되었다. 이제 개발자들은 이 두 클래스를 사용하여 좀더 간단하고 좀더 빠르게 시간과 관련해서 스케쥴링이 필요한 기능을 구현할 수 있을 것이다.

 

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

[출처] http://javacan.tistory.com/entry/29

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
204 스프링(Spring) 프레임워크 기본 개념 강좌 (6) - Dynamic Proxy 졸리운_곰 2017.10.02 71
203 스프링(Spring) 프레임워크 기본 개념 강좌 (5) - AOP Proxy file 졸리운_곰 2017.10.02 158
202 스프링(Spring) 프레임워크 기본 개념 강좌 (4) - AOP file 졸리운_곰 2017.10.02 109
201 스프링(Spring) 프레임워크 기본 개념 강좌 (3) - IoC file 졸리운_곰 2017.10.02 114
200 스프링(Spring) 프레임워크 기본 개념 강좌 (2) - 주요 구성 요소 & DI file 졸리운_곰 2017.10.02 107
199 스프링(Spring) 프레임워크 기본 개념 강좌 (1) - 스프링 이해하기 file 졸리운_곰 2017.10.02 290
198 Spring - IoC & DI file 졸리운_곰 2017.10.02 64
197 WebDAV 구현을 위한 환경 설정 file 졸리운_곰 2017.09.24 74
196 [subclipse] svn에서 무시할 파일 설정하기 svn:ignore property 설정 file 졸리운_곰 2017.09.24 145
195 다섯개의 탑 자바로 머신러닝 라이브러리 Top 5 machine learning libraries for Java file 졸리운_곰 2017.08.22 161
194 이진 파일, 이진 모드로 열어서 읽기 예제 소스 졸리운_곰 2017.05.20 135
193 Converting C# code in JAVA / datatype problem 졸리운_곰 2017.05.20 219
192 DwgFile.java - Joinup 졸리운_곰 2017.04.27 729
191 자바에서 C# 호출하기 file 졸리운_곰 2017.04.26 236
190 java4autocad Java for Autocad file 졸리운_곰 2017.04.26 257
189 Comparison between C# and Java - DiVA.pdf file 졸리운_곰 2017.04.25 682
188 [Java] Apache Commons HttpClient로 SSL 통신하기 졸리운_곰 2017.03.27 545
187 jsoup 사용하기 졸리운_곰 2017.03.27 116
186 Java Annotation: 인터페이스 강요로부터 자유를… file 졸리운_곰 2017.03.20 77
185 JSoup를 이용한 HTML 파싱 졸리운_곰 2017.03.04 100
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED