Java

자바 스케쥴링 & 타이머 방법들

[하마] 이승현 (wowlsh93@gmail.com) 2015. 5. 14. 13:41


 종종 어플리케이션은 백그라운드에서 정해진 시간간격으로 특정한 일을 하고 싶을때가 있습니다. 그때 사용하도록 아래와 같이 3가지 다른 스케쥴링하는 방법을 소개합니다.

  • simple thread 
  • TimerTask 
  • ScheduledExecutorService

1. simple thread

굳이 다른거 공부할필요없이 쓰레드를 직접 만들어서 단순하고 직관적으로 동작하게함. 

쓰레드 실행시키고 무한루프 돌면서리 run 내부에 sleep 으로 대기

01.public class Task1 {
02.public static void main(String[] args) {
03.
04.final long timeInterval = 1000;
05.Runnable runnable = new Runnable() {
06.public void run() {
07.while (true) {
08.// ------- code for task to run
09.System.out.println("Hello !!");
10.// ------- ends here
11.try {
12.Thread.sleep(timeInterval);
13.catch (InterruptedException e) {
14.e.printStackTrace();
15.}
16.}
17.}
18.};
19.Thread thread = new Thread(runnable);
20.thread.start();
21.}
22.}


2. the Timer and TimerTask

1번것은 매우 빠르고 쉬운데 몇가지 기능들이 없어서 불편을 초래할수도있는데 TimerTask 는 아래와 같은 기능을 추가해준다.

  • 태스크를 시작할때와 취소할때를 통제할수있게함.
  • 처음 시작할때 타이밍을 원하는데로 할수있음. 딜레이시킨다거나..

스케쥴링이 목적인 Timer class 와 태스크를 감싸는데 사용하는 TimerTask 클래스가 있는데 TimerTask 안에는 실행을 위한 run() 메소드가 있다. Timer 인스턴스는 여러가지 테스크를 실행할수 있으며 thread-safe 하다.

Timer 생성자가 불리워지면 , 하나의 쓰레드를 생성하고 이것은 태스크를 스케쥴링하기위해 사용된다. 여기서는  Timer#scheduleAtFixedRate 를 사용하였다.

01.import java.util.Timer;
02.import java.util.TimerTask;
03.public class Task2 {
04.public static void main(String[] args) {
05.
TimerTask task = new TimerTask() {
06.@Override
07.public void run() {
08.// task to run goes here
09.System.out.println("Hello !!!");
10.}
11.};
12.
Timer timer = new Timer();
13.long delay = 0;
14.long intevalPeriod = 1 1000;
15.// schedules the task to be run in an interval
16.timer.scheduleAtFixedRate(task, delay,
17.intevalPeriod);
18.// end of main
19.}

 JDK 1.3 부터 지원됨.

3. ScheduledExecutorService

이것은 Java SE5 의  java.util.concurrent 에서 소개된 유틸인데,  아래와 같은 기능상 

이득을 취할수있다.

  • Timer 들의 싱글쓰레드와 비교하여 쓰레드풀로서 실행된다.
  • 처음 실행시 딜레이를 제공하며 매우 유연하다.
  • 타임 인터벌을 제공하기위해  멋진 conventions 을 제공한다.
  • 보다 정확한 타임 인터벌 의 태스크 수행 

 ScheduledExecutorService#scheduleAtFixedRate 를 사용하였다.

01.import java.util.concurrent.Executors;
02.import java.util.concurrent.ScheduledExecutorService;
03.import java.util.concurrent.TimeUnit;
04.public class Task3 {
05.public static void main(String[] args) {
06.Runnable runnable = new Runnable() {
07.public void run() {
08.// task to run goes here
09.System.out.println("Hello !!");
10.}
11.};
12.ScheduledExecutorService service = Executors
13..newSingleThreadScheduledExecutor();
14.service.scheduleAtFixedRate(runnable, 01, TimeUnit.SECONDS);
15.}
16.}


4. scheduleAtFixedRate()   /   scheduleWithFixedDelay()의   차이


service.scheduleAtFixedRate(runnable, 0, 30, TimeUnit.SECONDS);

//0   : 시작 딜레이 (바로 시작하라) 
//30  : 3초에 한번 실행 


- scheduleAtFixedRate() 
 시작딜레이시  첫번째 실행을 시작으로 지정한 차이만큼 딜레이를 가지고 반복해서  실행 한다.

scheduleWithFixedDelay() 
시작딜레이(initialDelay) 이후 첫번째 실행을 시작으로 해당 command의 동작이 종료된 이후 다음 실행 시간까지 지정한 시간만큼 딜레이를 가지면서 반복 실행된다.