이전에 @Async를 활용하여 스프링이 생성해주는 스레드 풀을 이용해 클라이언트의 Http 요청 로직과는 별도로 비동기적으로 동작해야 하는 LocationMapper의 구현을 했다.

LocationMapper 로직의 특징은 webClient를 이용해 외부 kakao local api를 호출하여 작업을 수행한다는 것이다. 이 작업은 하나의 Ride 오브젝트 마다 동작하며 하나당 약 2초의 시간이 소요된다.

즉, Ride 데이터가 많으면 많을수록 너무 오래걸린다는 문제를 가지고 있다.

이를 해결하기 위해선 작업을 여러개로 분산하여 처리하는 방법이 있을것이다. 이를 병렬처리라 한다.

ExecutorService

자바에서 병렬처리를 위해서 ExecutorService를 제공한다.

스프링이 제공하는 @Async 또한 ExecutorService를 스프링 빈으로 생성하여 @Async 메소드를 호출할 때 ExecutorService의 Thread pool중 하나의 스레드에 Async 메소드를 실행시킴으로서 @Async 메소드를 호출한 메인 메소드와 별도로 병렬적으로 동작하도록 한 것이다.

ExecutorService는 초기에 설정해준 크기의 thread pool을 제공하는데 Spring의 AsyncConfig와 동일한 초기설정을 필요로 한다.

설정할 수 있는 요소는 corePoolSize, maxPoolSize, queueCapacity, AllowCoreThreadTimeOut, keepAliveSecond가 있다.

corePoolSize는 기본값은 1이며 threadPool에 동시에 동작할 수 있는 thread의 수를 의미한다. 즉 corePoolSize가 5라면 ThreadPool에서는 5개의 스레드가 동시에 동작할 수 있다.

queueCapacity는 corePoolSize만큼의 스레드가 이미 동작중일 때 새로운 요청이 발생한 경우 가용가능한 Thread가 생길 때 까지 동작을 보류하는 queue의 사이즈를 뜻한다.

그런데 여기서 이상한 점은 QueueSize를 넘어서더라도 새롭게 스레드를 생성하여 동작한다.

이를 설정하는 것이 maxPoolSize이다. 만약 corePool이 전부 동작중이고 queueSize를 넘어서는 요청이 발생하는 경우 동작할 수 있는 스레드를 maxPoolSize만큼 추가로 생성하는 것이다.

예를들어 corePoolSize가 2이고 QueueSize가 2일때 2개의 스레드가 동작중이라고 하자 그렇다면 이미 corePool은 전부 동작중이기에 추가로 2개의 요청이 발생하면 이 요청은 queue에 담기게 된다.