Timer 클래스는 유용한 클래스이다.
컴퓨터의 시간은 인간의 시간과 차이가 나기때문에 올바른 타이밍으로 시간을 콘트롤 하는 것은 프로그래머가 다루어야 할 문제이다.
자바 API 에는 여러 개의 Timer 클래스가 있다. 그 중에 기본적인 java.util.Timer 와 java.swing.Timer를 알아본다.
java.util.Timer 이렇게 되있는 것은 패키지 구조가 이렇게 되어 있어서 그렇다. Timer 는 클래스이고 java나 util 은 이를 분류하기 위한 디렉토리이다. 가끔 파이썬의 모듈과 혼동되는 경우가 있어서 주의한다.
파이썬은 모듈을 import 하더라도 그게 클래스가 아니다. 자바는 완전한 객체지향 프로그램이기 때문에 파일명 자체가 클래스라는 규칙이 차이가 난다.
같은 Timer 클래스 인데 java util 의 디렉토리의 Timer 와 java swing 디렉토리의 Timer 는 전혀 다른 클래스란 것을 알 수 있다. 한편 이클립스나 인텔리제이같은 IDE 에서는 어느 클래스인지 자동으로 감지가 안되니까 충돌이 없도록 사용자가 직접 지정해준다.
* Swing Timer
Swing 은 AWT 다음으로 나온 GUI API 인데 지금은 JavaFX 로 바뀌고 있다. 설령 JavaFX 를 사용하더라도 Swing 라이브러리 안에 있는 Timer 클래스는 GUI 의 그래픽 적 요소가 아니니까 상관없이 사용할 수 있다.
구현하는 방법은 간단하다. 매개변수 2개가 들어간다. delay 는 밀리세컨 1000분의 1초이고 , 액션리스너는 awt.event 패키지의 액션리스너 인터페이스를 사용하면 된다.
아래 코드와 같이 익명함수를 붙이면 된다.
delay 마다 같은 동작을 반복한다.
뒤에 Thread.sleep(5000) 을 시킨 것은 timer 만 실행시키면 코드가 그대로 종료되버린다. 저 코드를 실행시키는데는 아주 빛의 속도로 진행되기 때문에 뭐가 표시되는 것 조차 볼 수가 없다.
static void swingTimer(){
Timer timer = new Timer(200, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("new test");
}
});
timer.start();
try{
Thread.sleep(5000);
}catch(Exception e){}
timer.stop();
System.out.println("Closed");
}
실행시키면 5초간 0.2초 간격으로 실행되다가 Thread 가 끝나면 종료된다. Thread 는 시간을 지연시켜서 그동안 프로그램의 상태를 유지시킨다. 그렇지 않으면 이미 프로그램의 마지막 코드로 넘어가서 종료시켜 버린다.
* 다음은 java.util.Timer 이다.
구분을 위해서 패키지명까지 표시했다. 이 Timer 를 돌리려면 swing 과는 사용법이 다르다. TimerTask 클래스의 run 을 구현해야 한다. 간소한 작업을 하는데는 클래스 하나에 익명함수를 쓰는 swing 이 좀더 편하다고 할 수 있다.
timer.schedule 메서드로 작동을 시키는데 TimerTask 객체와 처음 시작시간, 그리고 반복되는 간격을 넣는다.
package com;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.TimerTask;
public class Main {
public static void main(String[] args) {
// write your code here
java.util.Timer timer = new java.util.Timer();
TimerTask task = new Helper();
timer.schedule(task, 1000, 1000);
}
}
class Helper extends TimerTask
{
int i = 0;
@Override
public void run() {
System.out.println("Timer Task running..."+ i++);
}
}
* 마지막으로 이 둘을 함께 실행시켜본다.
package com;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.TimerTask;
public class Main {
public static void main(String[] args) {
// write your code here
java.util.Timer timer = new java.util.Timer();
TimerTask task = new Helper();
timer.schedule(task, 1000, 1000);
swingTimer();
}
static void swingTimer(){
Timer timer = new Timer(200, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("new test");
}
});
timer.start();
try{
Thread.sleep(5000);
}catch(Exception e){}
timer.stop();
System.out.println("Closed");
}
}
class Helper extends TimerTask
{
int i = 0;
@Override
public void run() {
System.out.println("Timer Task running..."+ i++);
}
}
타이머 하나는 0.2 초, 다른 하나는 1초 간격으로 실행을 시키니 0.2초 5번에 1초 타이머가 1번 돌아가는 모습을 볼 수 있다. 이것은 딱히 로드가 없는 테스트 코드에 불과하지만 CPU의 작업시간 등 지연요소가 발생하면 타이밍이 바뀔 수 있다는 점에 주의한다. 타이밍은 동기화 기술이 더 중요하다. 이루어져야 할 작업의 순서와 절차가 중요하다,