JAVA Timer 클래스에 대하여
Timer / TimerTask 클래스
Timer클래스란?
말 그대로 정말 타이머(Timer)의 역할을 수행하는 클래스이다.
schedule이라는 내부 메서드를 통해 특성시간, 기간마다 인자로 받은 TimerTask인스턴스의 run메서드 로직을 수행하여 특정 시간마다 반복적인 로직을 실행하게끔하거나 하는 식으로 원하는 로직을 수행시킬 수 있다.
TimerTask 클래스란?
Timer클래스의 schedule함수로 작업 스케줄링을 관리할 때 들어가는 추상 클래스로,
Runnable클래스에서 run함수만 따와 별도의 스레드로 함수를 구동시키는 원리인 것같다.
사용 예제
우선 Timer클래스에 들어가면 생성자부터 schedule함수의 재정의에 따라 각각의 로직을 가지고있는데, 그것은 생략하겠다.
해당 예제에서 다루는 것은 Timer클래스의 생성, TimerTask의 정의, 이후 schedule에 함수에 들어간 TimerTask의 정상 작동 확인에 대해 다루겠다.
예제 1
ackage org.example;
import java.util.Timer;
import java.util.TimerTask;
//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class Main {
public static void main(String[] args) {
Timer timer = new Timer(); // 타이머 객체생성
TimerTask timerTask = new TimerTask() {
// 추상 클래스이므로 인스턴스 생성시에 가진 메서드를 구현해야함
@Override
public void run() {
System.out.println("시간이 지났습니다~"); // 작동 로직
timer.cancel(); // 타이머 종료
}
};
// 구동 후 5초 뒤에 timerTask의 로직을 구동한다.
timer.schedule(timerTask,5000);
}
}
아주 간단한 예제로 앱을 실행하고 5초뒤에 프린팅이 찍히게끔 되어있다.
TimerTask의 로직에 timer를 종료하는 cancel()를 사용하여 한번만 구동하게끔해놓았다.
왼쪽의 실행 시간을 보면 5초 후 구동이 완료되었고, 이후에 추가로 작동하지않고 종료됨을 알 수 있다.
그럼 타이머는 객체생성부터 작동될까, schedule()부터 구동될까?
객체 생성시부터 시간이 계산되는 것 같다. Timer의 클래스를 들어가보면
public Timer() {
this("Timer-" + serialNumber());
}
public Timer(String name) {
thread.setName(name);
thread.start();
}
이렇게 두개의 생성자가 있는데, 위 코드에서 기본생성자로 생성시 아래있는 타이머 생성자가 실행되면서 스레드가 시작됨으로 봤을때 생성자체가 실행된다고 . 볼수 있다.
특정 로직에만 실행시키기
그러면 특정 로직을 탈 때에 특정시간마다 실행을 시키려면, TimerTask만 미리 정의하거나 임의의 커스텀 클래스로 제작하여 빼고, 특정 로직을 탈때 타이머 인스턴스를 생성하면 되겠다.
아래는 해당 예제에 대한 코드이다.
우선 TimerTask를 커스터마이징했다.
public class CustomTimerTask extends TimerTask {
Timer timer;
public CustomTimerTask(Timer timer){
this.timer = timer;
}
@Override
public void run() {
System.out.println("타이머 로직이 실행됩니다.");
timer.cancel();
}
}
public class Main {
public static void main(String[] args) {
// 특정 로직을 실행하는지에 대한 bool 값
boolean isTimerExecute = false;
if (isTimerExecute) {
Timer timer = new Timer();
TimerTask timerTask = new CustomTimerTask(timer);
timer.schedule(timerTask,5000);
}else{
System.out.println("타이머를 타야하는 로직이 아닙니다.");
}
}
}
이렇게 한 후 실행해보겠다.
특정 로직이 아니기에 불과 224ms만에 실행되었고, 그대로 앱은 종료되었다. isTimerExecute 변수값을 true로 바꾼 후, 타이머 로직이 실행되는지 테스트해보자
기존처럼 5초뒤에 TimerTask에 실행이 한번 되었고, 추가 작동없이 타이머가 종료됨을 알 수 있다.
이렇게 Timer클래스와 TimerTask에 대해 알아보았다. 해당 클래스에 대한 역할은 Spring Framework같은 경우 스프링 스케줄러나 스프링 배치등 여러 대체 구현 기능이 되어있지만, 간단한 경우에는 해당 클래스로 커스터마이징을 해서 사용해도될 거 같다.