fragile and resilient

Java

[Java] Thread Pool

Green Lawn 2022. 9. 12. 00:02

Thread Pool은 매번 요청이 올 때마다 스레드를 생성하고 수거하는 것이 아닌, 설정한 스레드 수만큼 미리 생성하여 사용하는 것을 말합니다.

  • Thread Pool이 필요한 이유
    • 새로운 스레드를 생성할 때마다 스레드를 위한 메모리 영역(스택)을 확보하고, 스레드가 더 이상 필요 없으면 해당 메모리 영역을 회수하는데, 이는 오버헤드가 큰 작업입니다.

Executors 클래스의 정적 메서드를 통해 ExecutorService의 구현 객체를 제공받아 스레드 풀을 생성할 수 있습니다.

먼저 ThreadPoolExecutor를 설명하기 위해, Thread Pool 종류 중 하나인 newFixedThreadPool() 메서드를 살펴보겠습니다.

내부에서 ThreadPoolExecutor 클래스 생성자를 호출하고 있는데요.
해당 클래스는 스레드 풀을 관리해 주는 클래스입니다.

  • corePoollSize : 스레드 풀에서 스레드를 생성할 때 corePoollSize 수만큼 코어 스레드를 생성합니다.
  • maximumPoolSize : 모든 위에서 지정한 코어 스레드가 모두 사용 중이고, 내부 큐도 가득 찼을 경우 커질 수 있는 스레드 풀의 최대 크기입니다.
    • maximumPoolSize도 넘어가면 기본적으로 예외를 던진다. 
  • keepAliveTime : 현재 스레드 풀이 corePoolSize 보다 스레드가 많고, 초과한 스레드가 keepAliveTime 값보다 오랫동안 일하지 않으면 제거됩니다.
  • unit : 시간 단위
  • workQueue : corePoolSize가 가득 찼을 경우 스레드를 담아두는 대기 큐입니다.

Thread Pool 종류

1) Single Thread Executor

  • 단일 스레드
  • 단일 스레드가 실행 중 실패하거나 작업이 남은 경우 새로운 스레드를 생성합니다.
ExecutorService executorService = Executors.newSingleThreadExecutor();

2) Fixed Thread Executor

  • 고정된 개수의 쓰레드를 생성하고, 모든 쓰레드가 작업 중이라면 Task Queue 에서 대기합니다.
  • 실패 시 새로운 스레드를 생성합니다.
ExecutorService executorService = Executors.newFixedThreadPool(int nThreads);

3) Cached Thread Pool

  • 필요한 경우 새로운 스레드를 생성하며, 이전에 생성했던 스레드가 존재한다면 이를 재사용합니다.
  • 일반적으로 단기 비동기 작업을 많이 실행하는 프로그램에 좋습니다.
  • 60초 동안 사용되지 않은 스레드는 종료되고 캐시에서 제거됩니다.
ExecutorService executorService = Executors.newCachedThreadPool();

4) Scheduler Thread Pool

  • 설정한 Delay 이후에 실행하거나, 주기적으로 실행하도록 작업을 예약할 수 있습니다.
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(int corePoolSize);

스레드 풀에 작업 요청을 하는 방식은 execute( ), submit( ) 방식이 있습니다.

execute() 

  • 작업 처리 결과를 반환하지 않습니다.
  • 작업 처리 도중 예외 발생하면 스레드가 종료되고 해당 스레드는 스레드풀에서 제거하고, 스레드풀은 작업 처리를 위해 새로운 스레드를 생성합니다.

submit()

  • 작업 처리 결과를 반환합니다.
  • 작업 처리 도중 예외가 발생하더라도 스레드는 종료되지 않고 다음 작업을 위해 재사용됩니다.

execute 테스트

실행 결과 작업 처리 도중 예외가 발생하면 새로운 스레드(스레드 이름이 모두 다른 것을 확인하실 수 있습니다.)를 생성하는 것을 확인할 수 있었습니다.

submit 테스트

작업 처리 도중 예외가 발생하더라도 스레드가 종료되지 않고 계속 다음 작업에 재사용되는 것을 확인할 수 있습니다.


References

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor--
https://velog.io/@haero_kim/Java-Thread-Pool-개념과-동작원리

https://bepoz-study-diary.tistory.com/392