Projects/Team project - ShellWe

스레드 풀 관리 - new ThreadPoolTaskExecutor()

마손리 2023. 7. 12. 15:48

기능 구현중 비동기 처리를 해야될 상황이 생겨 new Thread().run()을 이용하여 비동기 처리를 진행 했었다.

하지만 이경우 스레드를 반복적으로 생성, 삭제가 이루어저 오버헤드가 발생하게 되어 다른 방법을 찾아 적용하게 되었다. 

 

일단 @Async 어노테이션을 사용해도 비동기 처리가 가능하지만 아무 설정없이 사용한다면 위와 마찬가지로 그저 스레드를 생성, 삭제 할뿐이었다. 그래서 스레드 풀을 위한 설정을 해주어야 했다.

 

 

스레드 풀 설정 bean 등록

@Configuration
@EnableAsync // Application이 아닌, Async 설정 클래스에 붙여야 함.
public class SpringAsyncConfig extends AsyncConfigurerSupport {

    @Bean(name = "threadPoolTaskExecutor")
    public Executor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(5); // 기본 스레드 수
        taskExecutor.setMaxPoolSize(30); // 최대 스레드 수
        taskExecutor.setQueueCapacity(100); // Queue 사이즈
        taskExecutor.setThreadNamePrefix("Executor-");
        return taskExecutor;
    }

}

@EnableAsync를 Application이 아닌 해당 설정 클래스에 붙여주고 AsyncConfigurerSupport를 상속받아 준뒤  new ThreadPoolTaskExecutor() 클래스를 인스턴스화 하여 스레드 풀에 관한 설정을 해준뒤 빈으로 등록해준다.

 

 

@Slf4j
@Component
public class AsyncService {
    ...
    ...
    @Async("threadPoolTaskExecutor")
    public void saveMessage(Map<Long, ChatRoom> chatRooms, TextMessage textMessage, long roomId, long memberId){
	...
        ...
    }
}

이후 비동기가 필요한 코드에 @Async("스레드 풀 설정 bean 이름")을 붙여 사용하면 된다.

 

 

주의사항

주의사항으로는 같은 클래스내에서 혹은 상속받은 클래스 안에서의 다른 메서드에 @Async 어노테이션을 붙이더라도 작동이 되지 않는다. 

 

이유로는 @Async 어노테이션은 AOP가 적용되어 그렇다고하는데... 아직 이걸 정확히 이해하는데에는 너무 어려웠다...

 

하이튼 그러한 이유로 위와 같이 새로운 클래스를 만들어 비동기 처리할 메서드만 따로 빼 작성해 주었다.

 

 

참고1 - 

https://velog.io/@gillog/Spring-Async-Annotation%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%A9%94%EC%86%8C%EB%93%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

 

참고2 - 

https://steady-coding.tistory.com/611