Thread의 개념

정인호·2025년 7월 16일

스레드

목록 보기
2/2

Spring Boot에서 API가 Thread로 동작한다는 의미

Spring Boot는 내부적으로 톰캣같은 웹 서버를 내장하고 있고, 이 톰캣은 Thread Pool을 이용해 요청마다 새로운 thread에서 처리하도록 되어 있다.

클라이언트 요청 -> 톰캣 -> thread pool에서 스레드 하나 꺼냄 -> 컨트롤러 메서드 실행

컨트롤러에서 만든 메서드는 이미 별도의 요청 처리용 스레드에서 실행 된다.
이 스레드는 보통 http-nio-8080-exec-1 같은 이름을 가진다.

직접 만든 Worker(Runnable 구현)와의 차이

public class Worker implements Runnable {
	@Override
    public void run() {
    	// 백그라운드 작업 수행
    }
}

직접 Thread, Runnable, ExecutorService 등을 이용해서 만든 스레드는 Spring의 요청/응답 처리 흐름과는 별개로 동작하는 수동 생성 백그라운드 작업이다.

예시)
1. 대용량 파일 처리
2. 주기적인 데이터 수집
3. Kafka, RabbitMQ 등의 메시지 큐 처리
4. 비동기 이메일 전송 등

위의 작업을 위해 별도의 스레드를 생성하여 사용한다.

주요 차이점 요약

  1. Spring Boot API 스레드
    1) 톰캣 내부의 스레드 풀이 스레드 생성
    2) HTTP 요청이 올 때 실행
    3) 요청 처리 용도
    4) 컨테이너(Tomcat)가 관리
    5) http-nio-8080-exec-1 등의 이름으로 명시

  2. 직접 구현한 Worker (Runnable 등)
    1) 개발자가 직접 스레드 생성
    2) 필요할 때 명시적으로 실행
    3) 백그라운드 작업, 비동기 처리 용도
    4) 개발자가 Thread 또는 Executor로 직접 관리
    5) 직접 설정하거나 기본 이름 사용

코드로 비교해 보면,

  1. Spring Boot API 호출
@RestController
public class Controller {
	
    @GetMapping("/hello")
    public String hello() {
    	// 이미 요청 처리용 스레드에서 실행됨
        return "Hello";
    }
}
  1. Runnable로 직접 스레드 생성
public class Worker implements Runnable {
	public void run() {
    	System.out.println("작업 수행 중...");
    }
}

new Thread(new Worker()).start(); // 메인 흐름과는 별개로 실행 됨

Spring Boot의 API는 내부적으로 톰캣 스레드 풀의 스레드에서 실행되므로, 개발자가 별도로 스레드를 만들지 않아도 멀티스레딩 환경에서 동작한다. 하지만, 요청과는 별도로 동작하는 지속적인 작업, 병렬 작업을 처리하려면 Runnable, Thread, @Async, ExecutorService 등을 사용해 직접 스레드를 만들어야 한다.

멀티스레딩 방식에 대한 개념

정의 : 하나의 프로세스 안에서 여러 개의 스레드가 동시에 실행되도록 하는 것
(단, "동시에"라는 건 CPU 스케줄링에 의해 논리적으로 동시에 보인다는 의미)

멀티스레딩의 활용 방식

1. 하나의 작업을 여러 스레드가 나눠서 병렬 처리

예) 이미지 필터링 작업을 4조각으로 나눠서 4개의 스레드가 각자 병렬로 처리함.

전체 작업: 큰 이미지 필터링
ㄴ Thread-1: 왼쪽 위
ㄴ Thread-2: 오른쪽 위
ㄴ Thread-3: 왼쪽 아래
ㄴ Thread-4: 오른쪽 아래

큰 작업을 나눠서 동시에 여러 스레드가 처리한다.
CPU 코어가 많을수록 빠르게 작업이 끝난다.

2. 여러 개의 서로 다른 작업을 각각의 스레드에 나눠서 실행

예)

  • Thread-1: 사용자 입력 받기
  • Thread-2: 파일 다운로드
  • Thread-3: 로그 출력
  • Thread-4: 메모리 정리

작업의 종류가 다르다.
동시에 병렬로 동작하여 앱 전체 성능을 향상 시킬 수 있다.

3. 스레드 풀 + 작업 큐 개념

멀티스레딩이지만 다른 개념

작업 리스트: [작업 A, 작업 B, 작업 C, 작업 D]
스레드 풀: Thread-1, Thread-2

작업 A -> Thread-1
작업 B -> Thread-2
작업 C -> Thread-1 (끝나고 다시 할당됨)
작업 D -> Thread-2 (끝나고 다시 할당됨)

즉,

  • 동시에 여러 작업이 실행되면 멀티스레딩
  • 작업들을 동시에 진행할 필요 없이 스레드를 효율적으로 재사용(스레드를 많이 안만들어도 됨)한다면, 스레드 풀을 통한 동시성 처리라고 한다.

마지막으로,
1. Worker 여러 개를 Thread로 생성해서 실행 하는 경우와

Worker worker1 = new Worker();
Worker worker2 = new Worker();

Thread t1 = new Thread(worker1);
Thread t2 = new Thread(worker2);

t1.start();
t2.start();
  1. Worker 여러 개를 만들었지만, Thread로 생성하지 않고 run() 만 호출한 경우
Worker worker1 = new Worker();
Worker worker2 = new Worker();

worker1.run(); // 단순 메서드 호출
worker2.run(); // 단순 메서드 호출

1번의 경우 멀티스레딩이지만 2번은 아니다.
Runnable 인터페이스를 구현했다 해도, Thread로 start() 하지 않으면 새로운 스레드가 만들어 지지 않아서 하나의 스레드씩 동기적으로 실행하는 싱글스레드 환경(2번)

profile
백엔드 개발자

0개의 댓글