애플리케이션 스레드
- 자바 애플리케이션 실행 시 JVM이 여러 `OS 커널 스레드`와 1:1 매핑을 띄움
- 그중, 우리가 직접 제어하고 코드를 실행시키는 스레드가 애플리케이션 스레드
- 메인 스레드, 스케줄러 스레드, 실행 스레드가 있다.
메인 스레드
: 프로그램의 진입점 `Public static void main()`에서 시작
: Spring Boot 애플리케이션 시작
스케줄러 스레드
: 주기적 작업 예약 및 실행 `ThreadPoolTaskScheduler`
: `@Scheduled`
실행 스레드
: 비동기 및 병렬 작업 수행 `ThreadPoolTaskExecutor`, `CompletableFuture`
: `@Async`, `runAsync( )`
= 모두 OS 커널 스레드와 1:1 매핑되어 동작한다.
ThreadPoolTaskScheduler - 스프링의 스케줄러 스레드 풀
스케줄 감시 + 실행을 모두 처리하는 스레드 풀, `@Scheduled`
- 내부 구조는 `ScheduledThreadPoolExcutor`(자바의 스케줄링 스레드 풀) 기반으로 스케줄링 + 실행 겸용
- `poolSize` 만큼 동시에 여러 스케줄러 작업을 병렬 실행 가능
- 오래 걸리는 작업을 직접 수행하면 블로킹되어 다른 스케줄 실행 지연이 발생
= 스케줄러는 트리거만 담당하고, 실제 작업은 실행 스레드풀에 위임하는 방식이 효율적이다.
ThreadPoolTaskExecutor - 스프링의 비동기 실행 스레드 풀
비동기 작업 실행 전용 스레드 풀, `@Async` `CompletableFuture`
- 내부 구조는 `ThreadPoolExcutor`(자바의 일반 스레드 풀) 기반으로 실행 전용 (스케줄링 기능 없음)
- `corePoolSize`, `maxPoolSize`, `queueCapacity` 등으로 병렬성 제어
- 단발성/비동기 작업 실행 전용
| 자바 기본 | ThreadPoolExecutor | 일반 스레드 풀 | 모든 Executor 기반 클래스 |
| 자바 기본 | ScheduledThreadPoolExecutor | 예약 + 실행 스레드 풀 | 주기 실행 |
| 스프링 확장 | ThreadPoolTaskExecutor | 비동기 실행 전용 | @Async, CompletableFuture |
| 스프링 확장 | ThreadPoolTaskScheduler | 예약 + 실행 관리 | @Scheduled |
=> 스케줄러를 여러 개 두는 것보다, 스케줄러는 한 개만 두고 내부에서 비동기 실행 스레드 풀을 사용하는 것이 효율적이다.
@Scheduled 가 동작하는 원리
1. 예약 등록
: 애플리케이션 시작 시 스프링이 `@Scheduled` 메서드 스캔
: 내부적으로 `ThreadPoolTaskScheduler` 에 해당 작업을 `Runnable` 형태로 등록
2. 스케줄 감시 및 실행 트리거
: `ThreadPoolTaskScheduler` 의 스케줄러 스레드 중 일부가 등록된 작업들의 다음 실행 시점을 계산하며 대기
: 시점에 도래하면 해당 `Runnable` 을 자신의 실행 큐로 등록
=> 이때까지 스케줄러 스레드는 감시만 하고, 비즈니스 로직은 수행되지 않음
3. 실행 수행
: 실행 큐에 들어간 작업은 `ThreadPoolTaskScheduler` 스레드 풀에서 스케줄러 스레드가 꺼내서 실행
: 해당 스레드가 주도권을 가져 내부 코드를 전부 수행
4. 비동기 전환 (선택)
: 내부에서 `@Async` 나 `CompletableFuture` 사용하면 다른 `ThreadPoolTaskExecutor` 풀로 위임
: 새로운 실행 스레드가 병렬로 작업을 처리
5. 종료 및 반환
: 작업이 끝난 스레드는 `ThreadPoolTaskScheduler` 나 `ThreadPoolTaskExecutor` 스레드 풀로 복귀
: `ThreadPoolTaskScheduler` 중 하나의 스레드는 스케줄 다음 주기 실행을 기다림
'💠프로그래밍 언어 > Java' 카테고리의 다른 글
| [기본 개념] 9 | (2.2) 스트림 중간 연산 (0) | 2022.02.10 |
|---|---|
| [기본 개념] 9 | (2.1) 스트림 (0) | 2022.01.26 |
| [기본 개념] 9 | (1.2) Java.util.funcion 패키지, Function 합성, Predicate 결합, 메서드 참조 (0) | 2022.01.26 |
| [기본 개념] 9 | (1.1) 람다식, 람다식 인터페이스 (0) | 2022.01.25 |
| [기본 개념] 8 | (1.6) 스레드 동기화(Lock, Condition, Volatile, Fork&Join 프레임웍 (0) | 2022.01.24 |