Executor Service와 Thread Pool

cotchan·2021년 8월 2일
0
post-custom-banner
  • 개인공부를 위한 목적으로 작성한 포스팅입니다.
  • 아래 출처를 참고하여 작성하였습니다.

1. Executor Service란?

  • 병렬작업 시 여러 개의 작업을 효율적으로 처리하기 위해 제공되는 라이브러리
  • Java에서 쓰레드풀을 생성해서 사용하고자 할 때 쓰는 유틸 클래스
  • ExecutorService에 Task만 지정해주면 친절하게 알아서 ThreadPool을 이용해서 Task를 실행하고 관리해줍니다.
  • Task는 Queue로 관리됩니다. ThreadPool에 있는 Thread수보다 Task가 많으면, 미실행된 Task는 Queue에 저장되고, 실행을 마친 Thread로 할당되어 순차적으로 수행됩니다.

1-1. Spring Default Executor

  • Spring 기본설정으로 되어 있는 TaskExecutorSimpleAsyncTaskExecutor입니다.
  • SimpleAsyncTaskExecutor에서는 어떤 스레드도 재사용하지않고 호출마다 새로운 스레드를 시작합니다.
  • 동시접속 제한(concurrency limit)을 지원 제한 수가 넘어서면 빈 공간이 생길 때까지 모든 요청을 block합니다.
  • 이런 방식은 리소스 낭비가 심하니 아래와 같은 Thread Pool을 재정의해서 사용하는 방식이 바람직합니다.

2. Basic Thread Pool


2-1. FixedThreadPool

  • 고정된 갯수를 가진 쓰레드풀입니다.
  • fixedThreadPool을 생성할때, 해당 머신의 CPU코어수를 기준으로 생성하면 더 좋은 퍼포먼스를 얻을 수 있습니다.

2-2. CachedThreadPool

  • 쓰레드를 캐싱하는 쓰레드풀입니다.
  • 일정시간 동안 쓰레드를 검사하여 60초동안 작업이 없으면 Pool에서 제거합니다.
  • Thread 갯수의 제한없이 무한정 생성하고, 해당 쓰레드의 작업이 60초간 없을 경우 Pool에서 제거하는 방식입니다.
  • 작업이 계속 쌓이는 환경에서는 해당 Thread가 소멸되는 것보다, 생성되는 양이 더 많을 수 있습니다.
  • 쓰레드 수가 폭발적으로 증가할 수 있다는 단점이 있습니다.

2-3. ScheduledThreadPool

  • 1분에 한 번씩 임무를 수행시키기 위한 쓰레드풀입니다.

2-4. SingleThreadExecutor

  • 한 개의 쓰레드로 작업을 처리하는 쓰레드풀입니다.
  • 싱글 쓰레드의 작업을 처리할때 고려해야 할 race-condition이라던지 하는 부분들을 알아서 처리합니다.

3. ForkJoin Pool

  • 큰 업무를 작은 업무로 나누어 배분해서, 일을 한 후에 일을 취합하는 형태
  • Task의 크기에 따라 분할(Fork)하고, 분할된 Task가 처리되면 그것을 합쳐(Join) 리턴해줍니다. 마치 분할정복 알고리즘처럼 동작합니다.

3-1. 탄생 배경

  • 쓰레드끼리 일을 나눠가져도 일 분배량의 차이 때문에 나머지 쓰레드의 유휴타임이 생기는 문제가 있습니다.
  • 다른 쓰레드들은 업무를 마쳤는데도 한 쓰레드만 일하고 있고, 나머지 쓰레드들은 멀뚱히 놀고만 있는 상황입니다.
  • 이런 문제를 해결하기 위해 나온 게 Fork Join 방식


3-2. 동작 방식

  • 쓰레드 A는 전체 잡을 받아서 자신의 로컬 큐에 1차 분할합니다.
  • 놀고있던 B 쓰레드는 A의 로컬 큐에서 잡을 훔쳐다가 일을 합니다.
  • 쓰레드 B가 훔쳐온 잡을 보니 양이 많아서 분할합니다.
  • 이런식으로 세부적으로 잡을 분할해서 모든 쓰레드가 골고루 가져가서 일하게 됩니다.
  • 모든 쓰레드가 일을 종료하는 시간이 비슷해집니다.

3-3. 장/단점

  • ForkJoin Pool을 쓸 때 빛을 발하게 되는 경우는 하나의 쓰레드가 굉장히 오래 걸리고 나머지 쓰레드들의 작업은 빨리 끝나는 경우에 빛을 발하게 됩니다.
  • 쓰레드에게 분할되는 Job이 거의 동일한 일을 하게 된다면 ForkJoinPool은 오히려 독이 될 수 있습니다. 쓸데없는 객체 생성을 하게 되기 때문입니다.

profile
https://github.com/cotchan
post-custom-banner

0개의 댓글