Thread 생명주기와 취소
JVM Thread 상태와 join·interrupt 기반의 협력적 취소를 이해한다.
이 문서의 목차
Overview
Thread 상태는 CPU 사용 여부가 아니라 JVM이 관찰한 실행 가능성과 대기 이유를 나타낸다. NEW → RUNNABLE → TERMINATED가 기본 흐름이고, 실행 중 Lock이나 조건을 기다리면 대기 상태로 이동한다.
stateDiagram-v2; [*] --> NEW; NEW --> RUNNABLE: start; RUNNABLE --> BLOCKED: monitor lock 대기; BLOCKED --> RUNNABLE; RUNNABLE --> WAITING: wait/join; WAITING --> RUNNABLE: notify/완료/interrupt; RUNNABLE --> TIMED_WAITING: sleep/timeout join; TIMED_WAITING --> RUNNABLE; RUNNABLE --> TERMINATED; TERMINATED --> [*]
BLOCKED와 WAITING
BLOCKED는 synchronized Monitor Lock 획득을 기다린다. WAITING은 join, wait, park처럼 다른 Thread의 완료나 조건 신호를 기다린다. 둘 다 CPU를 거의 쓰지 않지만 원인과 해결 방법이 다르다.
join과 interrupt
worker.join()은 호출한 현재 Thread가 worker의 종료를 기다린다는 뜻이다. interrupt()는 강제 종료가 아니라 대기를 깨우고 취소 요청을 전달한다. InterruptedException을 처리할 수 없는 Layer에서는 Thread.currentThread().interrupt()로 상태를 복원해 상위 호출자가 신호를 잃지 않게 한다.
try {
worker.join(3_000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}실무에서 발생하는 문제
Interrupt를 삼켜 종료가 멈추거나, Timeout 없는 join으로 무한 대기할 수 있다. Thread Dump에서 많은 BLOCKED는 Lock 경합, I/O Stack의 WAITING은 외부 자원 대기, 장시간 RUNNABLE은 CPU 작업의 단서지만 상태 하나만으로 결론 내리지 않고 Stack과 시간 변화를 함께 본다.
Interview Questions
- BLOCKED와 WAITING은 무엇을 기다리는가?
join호출 시 누가 누구를 기다리는가?- Interrupt Flag를 복원해야 하는 이유는?
- Thread Dump 상태만으로 장애 원인을 단정할 수 없는 이유는?
Related Topics
synchronized, Thread Pool과 함께 본다.
SOURCE REFERENCES
이 문서의 근거
본문은 Dev Atlas 안에서 완결되며, 검증이 필요할 때만 원문을 확인할 수 있습니다.