Love Every Moment

〔Java〕쓰레드 풀(Thread Pool) 본문

PROGRAMMING::LANGUAGE/Java

〔Java〕쓰레드 풀(Thread Pool)

해 송 2023. 8. 1. 10:14
반응형

1. 풀(Pool)

  • 이미 사용할 준비가 된 자원을 메모리 위에 일정량 미리 생성해둔 자원의 집합
  • 자원이 필요한 경우 새로 자원을 생성하는 대신 풀에서 꺼내어 사용
  • 자원 사용을 완료한 경우 자원을 해제하는 대신 풀에 다시 반환
자원의 생성과 파괴에 드는 비용, 즉 오버헤드(Overhead)를 줄여준다는 장점이 있다

 


 

2. 쓰레드 풀(Thread Pool)

출처:자바에서 쓰레드 풀 다뤄보기 (hudi.blog)

  • 미리 쓰레드들을 생성해두었다가 작업 요청이 들어올 때마다 미리 생성된 쓰레드로 작업을 처리
  • 작업이 끝난 쓰레드는 종료되지 않고 다음 작업 요청을 기다린다
  • 쓰레드들을 풀에 생성 → 작업들을 태스크 큐(Task Queue)에 추가 → 쓰레드 별로 작업을 할당하여 처리

 

3. 쓰레드 풀의 생성

출처: [자바 무료 강의] Thread Pool - 코드라떼 (codelatte.io)

java.util.concurrent 패키지의 Executors 클래스의 메소드를 이용하여 ExecutorService 객체 생성

 

(1) newCachedThreadPool()

ExecutorService threadPool = Executors.newCachedThreadPool();
  • 작업 요청이 들어올 때마다 쓰레드를 생성
  • 생성된 쓰레드가 60초동안 유휴 상태이면 제거됨
  • 초기 쓰레드 수: 0개
  • 코어 쓰레드 수: 0개
  • 최대 쓰레드 수: Integer.MAX_VALUE

(2) newFixedThreadPool()

ExecutorService threadPool = Executors.newFixedThreadPool(100);
  • 현재 존재하는 쓰레드 수보다 작업량이 많으면 쓰레드를 생성
  • 한 번 생성된 쓰레드는 유휴 상태가 오래 지나도 제거되지 않음
  • 초기 쓰레드 수: 0개
  • 코어 쓰레드 수: 쓰레드풀 생성시 지정
  • 최대 쓰레드 수: 쓰레드풀 생성시 지정

(3) ThreadPoolExecutor()

ExecutorService threadPool = new ThreadPoolExecutor(
        3, // 코어 쓰레드 수
        100, // 최대 쓰레드 수
        60, // 최대 유휴 시간
        TimeUnit.SECONDS, // 최대 유휴 시간 단위
        new LinkedBlockingQueue<Runnable>() // 작업 큐
);
  • 초기, 코어, 최대 쓰레드 수를 모두 마음대로 지정해서 쓰레드 풀을 생성하는 방법
  • 위의 newCachedThreadPool() 과 newFixedThreadPool() 도 내부적으로는 ThreadPoolExecutor()를 이용하여 구현되어 있음

 


4. 쓰레드 풀의 종료

(1) shutdown()

threadPool.shutdown();
  • 현재 쓰레드들이 처리하고 있는 작업과 작업 큐에 대기하고 있는 작업을 모두 끝마친 뒤에 쓰레드 풀을 종료

(2) shutdownNow()

List<Runnable> unprocessedTasks = threadPool.shutdownNow();
  • 현재 작업 중인 쓰레드를 강제 종료
  • 작업 큐 대기열에 남아있는 작업들은 List<Runnable> 로 반환

(3) awaitTermination()

boolean complete = threadPool.awaitTermination(60, TimeUnit.SECONDS);
  • shutdown() 을 먼저 호출
  • 지정한 timeout 안에 모든 작업이 완료되면 true 를 반환
  • 완료되지 못하면 작업을 처리 중이던 쓰레드를 강제 종료하고 false 를 반환

 


 

5. 쓰레드 풀에 작업 처리 요청

(1) execute()

  • Runnable 만 처리 가능
  • 작업의 처리 결과를 반환하지 않음
  • 쓰레드가 작업 처리 중에 예외가 발생하면, 쓰레드 풀에서 해당 쓰레드를 제거하고 새로운 쓰레드 생성

(2) submit()

  • Runnable 과 Callable 모두 처리 가능
  • 작업의 처리 결과를 Future 라는 인터페이스로 반환(→자바스크립트의 Promise 와 유사)
  • 작업 처리 중에 예외가 발생하더라도 쓰레드를 제거하지 않고 다음 작업에 재사용
  • 일반적으로 submit() 이 execute() 보다 오버헤드가 적으므로 권장됨
public class myCallable implements Callable {
    @Override
    public Integer call() {
        int count = 0;
        for (int i = 0; i < 10; i++) {
            try {
                count += 1;
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return count;
    }
}
Future<?> future = executorService.submit(new myCallable());
try {
    Object result = future.get(); // (1) 10초 동안 blocking 되었다가 반환
    System.out.println("10s"); // (2) 10초 후에 출력
    System.out.println("result = " + result); // (3) result = 10
} catch (Exception e) {
    e.printStackTrace();
}

 


 

참고

 

자바에서 쓰레드 풀 다뤄보기

프로세스와 쓰레드 쓰레드는 프로세스 내의 작업 흐름이다. 프로세스는 최소 1개의 쓰레드를 가지고 있으며, N개의 쓰레드를 생성하여 동시에 작업이 처리 되도록 구성할 수 있다. 이렇게 프로

hudi.blog

 

🧶 Java 에서 스레드 풀(Thread Pool) 을 사용해 보자

프로세스 내에서 스레드의 생성 및 수거가 빈번하게 발생한다면 메모리 할당에 소모되는 비용이 많이 들지 않을까? 이에 대한 해답으로 스레드 풀에 대해 알아보고 Java 에서 어떻게 사용하면 되

tecoble.techcourse.co.kr

 

 

자바와 쓰레드풀, 쓰레드의 생성비용

멀티 쓰레드와 생성비용

velog.io

 

[자바 무료 강의] Thread Pool

이번 강의는 Thread를 담고 있는 Thread Pool에 대해서 배워봅시다. 현업에서는 Thread Pool을 이용하여 작업을 처리하는 경우가 많습니다.

www.codelatte.io

Introduction to Thread Pools in Java | Baeldung

 

[Java] 멀티스레드를 통한 성능개선

화스트 페이스 경보 발생... 문제상황 프로젝트 진행 중 이번달 말에 계산을 돌려야하는데 시간이 오래 걸린다고 성능을 개선해달라는 요청을 받았다. Slow Query가 있겠거니 하고 소스를 뜯어봤더

foot-develop.tistory.com

 

 

ThreadPoolExecutor에 대한 오해와 진실

ThreadPoolExecutor에 대한 오해와 진실

leeyh0216.github.io

 

반응형
Comments