1. java.util.concurrent 패키지
이 패키지는 실행자 프레임워크 (Executor Framework) 라고 하는, 인터페이스 기반의 태스크 실행 기능을 담고 있다. 클라이언트 요청에 의해 쌓인 작업 큐를 생성할 수 있는 코드를 단 한줄로 작성할 수 있다.
// 작업 큐를 생성하다.
ExcutorService exec = Executors.newSingleThreadExcutor();
그리고, 이 실행자에 실행할 태스크를 넘기는 방법도 단 한줄로 작성할 수 있다.
// 다음은 이 Excutor에 실행할 태스크(task; 작업)를 넘기는 방법이다.
exec.execute(runnable);
그리고, 실행자를 종료시킬 수 있다.
exec.shutdown();
실행자 서비스의 기능은 이 외에도 많은데, 아래는 실행자 서비스의 주요 기능들이다.
1. 특정 태스크가 완료되기를 기다린다. (get 메서드)
2. 태스크 모음 중 아무것 하나 (invokeAny 메서드) 혹은 모든 태스크 (invokeAll 메서드) 가 완료되기를 기다린다.
3. 실행자 서비스가 종료하기를 기다린다. (awaitTermination 메서드)
4. 완료된 태스크들의 결과를 차례로 받는다 (ExecutorCompletionService 이용)
5. 태스크를 특정 시간에 혹은 주기적으로 실행한다. (ScheduledThreadPoolExecutor 이용)
1-1. 실행자 서비스를 사용하기에 까다로운 경우
작은 프로그램이나 가벼운 서버를 사용할 때에는 Executors.newCachedThreadPool 실행자 서비스를 사용할 수 있다. 특별히 설정할 게 없고, 일반적인 용도에 적합하다. 하지만, 무거운 서버에선 좋지 못한데, CachedThreadPool 에서 요청받은 태스크들은 큐에 쌓이지 않고 즉시 스레드에 위임된다. 가용한 스레드가 없다면 새로 하나 만든다. CPU 가 100%로 치닫고, 계속 새로운 스레드를 만들며 상황이 악화될 수 있다. 이 경우엔, 스레드가 고정된 Executors.newFixedThreadPool 을 선택하자.
1-2. 정리
작업 큐, 스레드를 직접 생성하거나 다루지 말고, 실행자 프레임워크를 사용하자.
태스크 수행을 실행자 서비스에 맡기면 원하는 태스크 수행 정책을 선택할 수 있고, 언제든 변경할 수 있다. 실행자 프레임워크가 작업 수행을 담당해주기 때문이다.

'1️⃣ 백앤드 > 이펙티브 자바' 카테고리의 다른 글
| [아이템82] 스레드 안전성 수준을 문서화해라 (0) | 2024.12.19 |
|---|---|
| [아이템81] wait 와 notify 보다는 동시성 유틸리티를 애용해라 (0) | 2024.12.18 |
| [아이템79] 과도한 동기화는 피하라 (0) | 2024.12.12 |
| [아이템78] 공유 중인 가변 데이터는 동기화해 사용하라 (0) | 2024.12.11 |
| [아이템77] 예외를 무시하지 말라 (0) | 2024.12.11 |