오늘 한 일
- JAVA 복습 (chap12. 멀티스레드 후반부)
배운 것
- 스레드 그룹의 생성과 일괄 interrupt()
- 스레드풀(ThreadPool): 작업 큐(Queue)에 들어오는 작업들을 제한된 개수의 스레드가 하나씩 맡아서 처리함으로써 갑작스런 병렬 작업의 폭증으로 인한 스레드 폭증을 예방
- 스레드풀 생성: ExecutorService 객체 생성
- 작업은 Runnable 또는 Callable 구현 클래스로 표현. 작업 처리 후 리턴값이 없으면 Runnable, 리턴값이 있으면 Callable
- Runnable은 run()을, Callable은 call()을 구현해야 함
- 작업 처리 요청: ExecutorService의 작업 큐에 Runnable/Callable 객체를 넣는 행위
- submit()을 사용하여 작업 처리를 요청(인자로 Runnable/Callable 작업 객체 전달)하고 리턴된 Future를 통해 작업 처리 결과를 얻는다. 결과를 얻지 않는 경우 Runnable 작업 객체를 인자로 받는 execute()를 사용할 수 있다.
- 작업 처리 도중 예외 발생 시 해당 작업을 처리하던 스레드가 종료되고 스레드풀에서도 제거되는 execute()와 달리, submit()은 작업을 처리하던 스레드가 다른 작업을 처리하는 데 재사용되기 때문에 스레드 생성 오버헤드를 줄인다.
- 작업 완료의 통보 (Future.get()을 사용한 블로킹 방식)
Future future = executorService.submit(Runnable task);
Future<T> future = executorService.submit(Callable<T> task);
try {
future.get();
T result = future.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
- 작업 처리 결과를 외부 객체에 저장 및 취합하기 위해 공유 객체를 각 Runnable 작업 객체가 필드로 갖게 하고 ExecutorService의 submit(Runnable task, V result) (V는 공유 객체 Result의 타입)을 사용하여 Future<V> future.get() 을 호출한다.
- 먼저 완료된 작업 결과를 받기: CompletionService 구현 객체의 poll() 또는 take() 메소드를 사용하여 먼저 처리된 작업의 Future를 얻을 수 있음.
- 콜백(Callback) 방식의 작업 완료 통보: 작업 처리 요청 후 기다릴 필요 없이 작업이 완료되면 콜백 메소드를 실행하게 하여 결과를 확인
- 콜백 메소드는 직접 구현하거나 CompletionHandler 사용
- CompletionHandler 객체: completed() - 작업이 정상 처리 완료되었을 때 호출되는 콜백 메소드, failed() - 작업 처리 도중 예외 발생 시 호출되는 콜백 메소드(docs). Runnable 작업 객체의 run() 메소드에서 콜백 메소드 호출하여 콜백 기능 구현(예제)
- 콜백 방식과 블로킹 방식 (source)
내일 할 일
- JAVA 복습 (chap13,14. 제네릭, 람다식)