만약 고객의 주문을 처리하는 서버를 운영중인데, 서버를 재시작해야 한다고 가정해보자. 이때 고객의 주문을 처리하고 있는 도중에 갑자기 재시작하면 해당 고객의 주문이 제대로 진행되지 못할 것이다. 따라서 새로운 주문 요청은 막고, 이미 진행중인 주문은 모두 완료한 후에 서버를 재시작하는 것이 가장 이상적이다.
이처럼 서비스를 안정적으로 종료하는 것도 매우 중요하다. 이렇게 문제 없이 우아하게 종료하는 방식을 graceful shutdown이라고 한다.
ExecutorService의 종료 메서드
ExecutorService의 종료 관련 메서드는 다음과 같다.
서비스 종료
void shutdown()
- 새로운 작업을 받지 않고, 이미 제출된 작업을 모두 완료한 후에 종료한다.
- 논블로킹 메서드이다. 즉, 이 메서드를 호출한 스레드는 대기하지 않고 즉시 다음 코드를 호출한다.
- 만약 처리 중인 작업이 없다면,
- shutdown()을 호출한다.
- ExecutorService는 새로운 요청을 거절한다. 거절 시 기본적으로 java.util.concurrent.RejectedExecutionExeception 예외가 발생한다.
- 스레드 풀의 자원을 정리한다.
- 반면 처리 중인 작업이 있는 경우,
- shutdown()을 호출한다.
- ExecutorService는 새로운 요청을 거절한다.
- 스레드 풀의 스레드는 처리 중인 작업을 완료한다. 그리고 큐에 남아있는 작업도 모두 꺼내서 완료한다.
- 모든 작업을 완료하면 스레드 풀의 자원을 정리한다.
List<Runnable> shutdownNow()
- 실행 중인 작업을 중단하고, 대기 중인 작업을 반환하며 즉시 종료한다.
- 실행 중인 작업을 중단하기 위해 인터럽트를 발생시킨다.
- 논블로킹 메서드이다.
- 만약 처리 중인 작업이 있는 경우,
- shutdown()을 호출한다.
- ExecutorService는 새로운 요청을 거절한다.
- 큐를 비우면서, 큐에 있는 작업을 모두 꺼내서 컬렉션으로 반환한다. (List<Runnable> runnables = es.shutdownNow())
- 작업 중인 스레드에 인터럽트가 발생한다.
- 모든 작업을 완료하면 스레드 풀의 자원을 정리한다.
close()
- 자바 19부터 지원하는 메서드로, shutdown()과 유사하다.
- shutdown()을 호출하고, 하루를 기다려도 작업이 완료되지 않으면 shutdownNow()를 호출한다.
- 호출한 스레드에 인터럽트가 발생해도 shutdownNow()를 호출한다.
서비스 상태 확인
boolean isShutdown()
- 서비스가 종료되었는지 확인한다.
boolean isTerminated()
- shutdown(), shutdownNow() 호출 후 모든 작업이 완료되었는지 확인한다.
작업 완료 대기
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException
- 서비스 종료 시 모든 작업이 완료될 때까지 대기한다.
- 이때 지정한 시간만큼만 대기한다.
- 블로킹 메서드이다.
Reference
- 김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
'Language > Java' 카테고리의 다른 글
자바에서의 모니터(synchronized, wait() & notify(), Condition)와 생산자-소비자 문제 (0) | 2024.10.23 |
---|---|
ExecutorService의 스레드 풀 관리 (1) | 2024.10.21 |
Executor 프레임워크(ExecutorService, Callable, Future) (0) | 2024.10.18 |
인터럽트 (0) | 2024.10.14 |
자바에서 자식 메서드가 부모 메서드가 던지는 체크 예외의 하위 타입만 던질 수 있는 이유 (0) | 2024.10.14 |