훈훈훈
Spring boot :: Task Execution and Scheduling 본문
아래 내용은 스프링 공식문서 스터디에서 정리했던 자료 입니다.
Task Execution and Scheduling
1. Executor
(1) Executor 란?
- Java 5에 도입되었으며, 단순히
void execute(Runnable command);
메서드만 정의된 객체이다. - command 를 실행할 때 마다 새로운 스레드에 동작
- command 는 Runnable 인터페이스 객체이다.
- Executor 가 실행될 때는 쓰레드를 명시하지 않는다고 한다. 그 역할은 Runnable 인터페이스가 대신한다.
executor.execute(new RunnableTask());
이런 식으로 command 를 실행 시킨다.
(2) Runnable Interface
- 자바에서는 Thread 를 구현할 때 Thread 클래스를 사용하거나 Runnable 인터페이스를 사용할 수 있다.
- 두 방법의 차이는 다중 상속이 가능한지에 대한 내용이며, 상황에 맞게 사용하는 것이 좋다.
- Thread 클래스를 사용하는 경우 다중 상속이 불가능 하며, Runnable 인터페이스를 사용하는 경우 다중 상속이 가능하다.
- 위 코드는 Runnable 인터페이스의 코드이며, 주석을 살펴보면 Runnable 인터페이스의 구현체가 create a thread 를 할 때, 구현체의 run 메서드를 실행시킨다.
2. ThreadPoolTaskExecutor
(1) ThreadPoolTaskExecutor 란 ?
- Spring 에서 쓰레드를 관리해주는 역할을 하며, Executor 를 최상위 인터페이스로 가지고 있다.
- 자바의 ThreadPoolExecutor 를 사용하기 쉽게 만들어 사용할 수 있도록 해주는 일종의 Wrapper 클래스라고 보면 편하다.
- 코드
- 상속 관계
- ThreadPoolTaskExecutor 클래스는
AsyncListenableTaskExecutor
,SchedulingTaskExecutor
인터페이스를 상속 받고 있는 것을 볼 수 있다. - 두 인터페이스 모두
AsyncTaskExecutor
인터페이스를 extends 하고 있다. - 그리고 AsyncTaskExecutor 인터페이스는 Executor 인터페이스를 exntends 하고 있는 TaskExecutor 인터페이스를 extends 하고 있다.
(2) AsyncListenableTaskExecutor
- add submit 할 때, ListenableFutures 기눙을 추가하기 위해 만들어진 인터페이스이다.
- ListenableFutures는 Executor에 Task 를 전달하고 돌려 받는 Future 타입의 종류 중 하나이다.
- Runnable 인터페이스 객체인 task 를 던지는 것을 볼 수 있다.
(3) SchedulingTaskExecutor
- 해당 인터페이스는 힌트 (플래그)로만 사용된다 ??
- 반복된 루프를 개별 하위 작업으로 분할하여 이후 후속 작업을 submit 할 수 있다.
(4) AsyncTaskExecutor
- TaskExecutor 를 상속한 인터페이스이다.
- submit 메서드와 timeout 기능이 추가되었다.
스프링에서는
@EnableAsync
어노테이션을 추가하면 디폴트로SimpleAsyncTaskExecutor
구현체를 사용한다.SimpleAsyncTaskExecutor 객체는 매번 Thread 를 생성하는 객체이기 때문에 쓰레드 풀내에서 지정된 갯수 만큼만 실행 시키고 싶다면 아래와 같이 ThreadPool 설정이 필요하다.
사용 예제 (@EnableAsync 주석 예제)
@Configuration @EnableAsync public class AsyncConfig extends AsyncConfigurerSupport { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(7); executor.setMaxPoolSize(42); executor.setQueueCapacity(11); executor.setThreadNamePrefix("MyExecutor-"); executor.initialize(); return executor; } }
스프링 부트에서는 아래와 같이 프로퍼티로 ThreadPoolTaskExecutor 를 설정할 수 있다.
왜냐하면
Executor
객체가 Bean으로 등록이 되지 않았다면ThreadPoolTaskExecutor
객체를 auto-configure 하기 때문이다.spring.task.execution.pool.max-size=16 spring.task.execution.pool.queue-capacity=100 spring.task.execution.pool.keep-alive=10s
참고
'Spring Framework > 개념' 카테고리의 다른 글
Spring boot :: JPA, Mybatis Transaction Manager 정리 (1) | 2021.09.06 |
---|---|
Spring boot :: Datasource Replication 구현 (1) | 2021.09.05 |
Spring boot :: JPA @EntityListeners 정리 (0) | 2021.03.22 |
Spring boot :: JdbcTemplate을 사용하여 batch insert 기능 구현 (2) | 2021.01.17 |
Spring boot :: QueryDSL을 사용해서 No Offset Paging 구현하기 (0) | 2021.01.10 |
Comments