reference : https://steady-coding.tistory.com/548
스레드 풀 개념
- 멀티 스레드 환경에서 병렬 작업 처리가 많아지면 스레드 개수가 증가하고 그에 따른 스레드 생성과 스케쥴링으로 인해 CPU에 과부하가 오고 메모리 사용량이 증가한다. 이는 애플리케이션의 성능 저하로 이어진다.
- 병렬 작업의 폭증으로 인한 스레드의 폭증을 막기위해 스레드 풀 기법을 사용한다.
- 스레드 풀은 작업 처리에 사용되는 스레드를 제한된 개수만큼 정해 놓고 작업 큐에 들어오는 작업들을 하나식 스레드가 맡아 처리한다
- 따라서 작업 처리 요청이 폭증해도 작업 큐라는 곳에 작업이 대기하다가 여유가 있는 스레드가 그것을 처리하므로 스레드의 전체 개수는 일정하며 애플리케이션의 성능도 저하되지 않는다.

스레드 풀 생성 및 종료
- 자바는 스레드 풀을 생성하고 사용할 수 있도록 java.util.concurrent 패키지에서 ExecutorService 인터페이스와 Executors 클래스를 제공한다.
스레드 풀 생성
- ExecutorService 구현 객체는 Executors 클래스의 다음 두 가지 메소드 중 하나를 이용해서 간편하게 생성할 수 있다

- 초기 스레드 수: ExecutorService 객체가 사용될 때 기본적으로 생성되는 스레드 수
- 코어 스레드 수: 스레드 수가 증가된 후 사용되지 않는 스레드를 스레드 풀에서 제거할 때 최소한 유지해야 할 스레드 수
- 최대 스레드 수: 스레드 풀에서 관리하는 최대 스레드 수
newCachedThreadPool() 메소드는 1개 이상의 스레드가 추가되었을 경우 60초 동안 스레드가 아무 작업하지 않으면 해당 스레드를 풀에서 쫓아내는데, newFixedThreadPool(int nThreads) 메소드는 스레드가 놀고 있어도 제재를 가하지 않는다.

스레드 풀 종료
- 기본적으로 스레드 풀의 스레드는 데몬 스레드가 아니므로 main 스레드가 종료되더라도 프로세스는 계속 실행중이다.
- 따라서 main 스레드가 종료되면 해당 스레드 풀을 종료해야한다.
메소드 종류
- shutdown()
- void 리턴 타입
- 현재 처리 중인 작업 뿐만 아니라 작업 큐에 대기하고 있는 모든 작업을 처리한 뒤에 스레드 풀을 종료한다.
- shutdownNow()
- List 리턴 타입
- 현재 작업 처리 중인 스레드를 interrupt해서 작업 중지를 시도하고 스레드 풀을종료한다.
- 리턴 값은 작업 큐에 있는 미처리된 작업의 목록이다.
- awaitTermination(long timeout, TimeUnit unit)
- boolean 리턴 타입
- shutdown() 메소드 호출 이후, 모든 작업 처리를 timeout 시간 내에 완료하 면 true를 리턴하고, 그렇지 않으면 작업 처리 중인 스레드를 interrupt하고 false를 리턴한다.
예상 면접 질문 및 답변
스레드 풀이란?
- 스레드 풀은 작업 처리에 사용되는 스레드를 제한된 개수만큼 정해 놓고, 작업 큐에 들어오는 작업들을 하나씩 스레드가 맡아 처리하는 기법이다.
스레드 풀을 왜 사용하는가?
-
병렬 작업 처리가 많아지면 스레드 개수가 중가되고, 그에 따른 스레드 생성과 스케줄링으로 인해 CPU가 바빠져 메모리 사용량이 늘어난다. 이는 애플리케이션의 성능 저하로 이어진다.
-
스레드 풀은 작업 처리에 사용되는 스레드를 제한된 개수만큼 정해 놓고, 작업 큐에 들어오는 작업들을 하나씩 스레드가 맡아 처리한다.
-
작업 처리가 끝난 스레드는 다시 작업 큐에서 새로운 작업을 가져와 처리한다.
따라서 작업 처리 요청이 폭증해도 작업 큐라는 곳에 작업이 대기하다가 여유가 있는 스레드가 그것을 처리하므로 스레드의 전체 개수는 일정하며 애플리케이션의 성능도 저하되지 않는다.
작업 완료 통보에서 블로킹 방식(동기)과 콜백 방식(비동기)의 차이
- 블로킹 방식은 작업 처리를 요청한 후 작업이 완료될 때까지 블로킹되지만, 콜백 방식은 작업 처리를 요청한 후 결과를 기다릴 필요 없이 다른 기능을 수행할 수 있다.