Files
java-examples/docs/Concurrency/03_Timer.md

198 lines
8.2 KiB
Markdown

### 자바의 `Timer`와 `TimerTask`에 대한 설명
자바에서 `Timer``TimerTask`는 특정 작업을 일정 시간 간격으로 또는 지정된 시간에 실행하기 위한 유틸리티 클래스입니다. `java.util` 패키지에 포함되어 있으며, 스레드를 기반으로 동작하여 비동기적으로 작업을 스케줄링할 수 있습니다. 아래에서는 이와 관련된 클래스 및 메서드를 표로 정리하고, 예시와 함께 설명하겠습니다.
---
### `Timer`와 `TimerTask` 관련 클래스 및 메서드 표
#### `Timer` 클래스
| 메서드명 | 반환 타입 | 설명 |
|-----------------------------------|-----------|---------------------------------------------------------------------------------------|
| `Timer()` | - | 새로운 `Timer` 객체를 생성 |
| `schedule(TimerTask, long delay)`| `void` | 지정된 지연 시간(밀리초) 후에 `TimerTask`를 한 번 실행 |
| `schedule(TimerTask, Date time)` | `void` | 지정된 시간(`Date`)에 `TimerTask`를 한 번 실행 |
| `schedule(TimerTask, long delay, long period)` | `void` | 지정된 지연 시간 후 주기적으로(밀리초 단위) `TimerTask`를 반복 실행 |
| `scheduleAtFixedRate(TimerTask, long delay, long period)` | `void` | 지정된 지연 시간 후 고정된 주기로 `TimerTask`를 반복 실행 (지연 보정 없음) |
| `cancel()` | `void` | `Timer`를 종료하고 모든 스케줄링된 작업을 취소 |
| `purge()` | `int` | 취소된 작업을 큐에서 제거하고 제거된 작업 수를 반환 |
#### `TimerTask` 클래스
| 메서드명 | 반환 타입 | 설명 |
|-----------------------------------|-----------|---------------------------------------------------------------------------------------|
| `run()` | `void` | `Timer`에 의해 실행될 작업을 정의 (추상 메서드, 오버라이드 필요) |
| `cancel()` | `boolean` | 해당 `TimerTask`의 스케줄링을 취소하고 성공 여부를 반환 |
| `scheduledExecutionTime()` | `long` | 해당 작업이 마지막으로 스케줄링된 시간을 반환 (밀리초 단위) |
---
### `Timer`와 `TimerTask` 설명 및 예시
`Timer`는 백그라운드 스레드를 생성하여 작업을 스케줄링하고, `TimerTask`는 실행할 작업을 정의하는 추상 클래스입니다. `TimerTask`를 상속받아 `run()` 메서드를 구현한 후, `Timer``schedule` 메서드로 작업을 등록합니다. 주요 사용 사례는 주기적인 알림, 로그 기록, 상태 점검 등입니다.
#### 1. 기본 사용: 일정 시간 후 한 번 실행
`schedule(TimerTask, long delay)`를 사용해 지정된 지연 시간 후 작업을 한 번 실행합니다.
```java
import java.util.Timer;
import java.util.TimerTask;
public class SimpleTimerExample {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("작업 실행: " + System.currentTimeMillis());
}
};
timer.schedule(task, 2000); // 2초 후 실행
System.out.println("스케줄링 완료: " + System.currentTimeMillis());
}
}
```
- **출력 예시**:
```
스케줄링 완료: 1678321234567
(2초 후)
작업 실행: 1678321236567
```
#### 2. 주기적 실행: 고정 주기 반복
`schedule(TimerTask, long delay, long period)`를 사용해 주기적으로 작업을 반복합니다.
```java
import java.util.Timer;
import java.util.TimerTask;
public class PeriodicTimerExample {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
int count = 0;
@Override
public void run() {
count++;
System.out.println("작업 실행 " + count + "회: " + System.currentTimeMillis());
if (count == 3) {
timer.cancel(); // 3회 실행 후 종료
System.out.println("타이머 종료");
}
}
};
timer.schedule(task, 1000, 2000); // 1초 후 시작, 2초마다 반복
}
}
```
- **출력 예시**:
```
(1초 후)
작업 실행 1회: 1678321235567
(2초 후)
작업 실행 2회: 1678321237567
(2초 후)
작업 실행 3회: 1678321239567
타이머 종료
```
#### 3. 고정 속도 실행: `scheduleAtFixedRate`
`scheduleAtFixedRate`는 작업 간 간격을 고정하며, 지연이 발생하더라도 이를 보정하지 않고 계속 실행합니다.
```java
import java.util.Timer;
import java.util.TimerTask;
public class FixedRateTimerExample {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
int count = 0;
@Override
public void run() {
count++;
System.out.println("작업 실행 " + count + "회: " + System.currentTimeMillis());
try {
Thread.sleep(1500); // 작업 시간이 주기보다 길어짐
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 3) {
timer.cancel();
}
}
};
timer.scheduleAtFixedRate(task, 1000, 1000); // 1초 후 시작, 1초마다 실행 시도
}
}
```
- **출력 예시**:
```
(1초 후)
작업 실행 1회: 1678321235567
(1.5초 후, 지연 발생)
작업 실행 2회: 1678321237067
(1.5초 후)
작업 실행 3회: 1678321238567
```
- **설명**: `scheduleAtFixedRate`는 주기를 엄격히 유지하려 하지만, 작업 시간이 주기(1초)보다 길어지면 다음 실행이 바로 이어집니다.
#### 4. 작업 및 타이머 취소
`TimerTask.cancel()`로 개별 작업을, `Timer.cancel()`로 모든 작업을 취소할 수 있습니다.
```java
import java.util.Timer;
import java.util.TimerTask;
public class CancelTimerExample {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("작업 실행");
}
};
timer.schedule(task, 1000, 1000); // 1초 후 시작, 1초마다 반복
try {
Thread.sleep(2500); // 2.5초 대기
} catch (InterruptedException e) {
e.printStackTrace();
}
task.cancel(); // 개별 작업 취소
System.out.println("작업 취소됨");
timer.cancel(); // 타이머 종료
System.out.println("타이머 종료");
}
}
```
- **출력 예시**:
```
(1초 후)
작업 실행
(1초 후)
작업 실행
작업 취소됨
타이머 종료
```
---
### `Timer`와 `TimerTask`의 장점과 한계
- **장점**:
- 간단한 스케줄링 작업에 적합.
- 구현이 쉬움.
- **한계**:
- 단일 스레드로 동작하므로 하나의 작업이 지연되면 다른 작업에도 영향을 미침.
- 예외 발생 시 `Timer`가 종료될 수 있음.
- 복잡한 스케줄링에는 `ScheduledExecutorService`가 더 적합.
---
### 결론
`Timer`와 `TimerTask`는 주기적이거나 지연된 작업을 간단히 처리할 때 유용합니다. `schedule`과 `scheduleAtFixedRate`를 통해 다양한 스케줄링 요구를 충족할 수 있으며, `cancel`로 작업을 제어할 수 있습니다. 위 예시를 참고하여 실제 애플리케이션에서 활용해 보세요! 더 복잡한 경우에는 `java.util.concurrent.ScheduledExecutorService`를 고려하는 것도 좋은 대안입니다.