Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- aws #ec2 #instance #클라우드 #cloud #it
- 인터페이스
- Tomcat
- Spring REST Docs #Swagger #JAVA #REST API
- 인스턴스오류 #Tomcat #mysql
- 서버이전
- 오류해결
- brew #mariadb #Django #Python
- 바인딩
- 클래스명과 파일명 동일한 이유
- iBATIS
- sql린이#공부중
- Java
- 포트폴리오 작성
- 자바프로그래밍
- 나중에도 같은문제면 이렇게 시도해봐야겠다
- JSON #javascript
- ROLLUP#합계
- 서터 세팅이 잘못인가
- Integer
- dockerfile #dockerrun #빌드
- list
- 클래스명
- 개발자포트폴리오
- WORK폴더
- 클래스
- Spring #Scheduler #JAVA
- 객체정렬 #Java8
- ArrayList
- 근데왜지
Archives
- Today
- Total
HoneyBee
멀티 스레드 @Async 사용기, CompletableFuture 본문
사용계기
- 필자가 AWS sdk를 활용하여 각 리소스의 데이터를 가져와 대시보드에 보여주는 API를 개발
- 각각의 모듈을 불러오는 중, 속도 저하 문제 발생
- 멀티스레드로 구현을 위해 리서치 중 @Async확인
개념
- Spring 에서 쓰레드 풀을 활용한 비동기 메소드를 지원
- 메소드에 @Async를 달아두면 비동기로 리턴하고 spring TaskExecutor로 새로운 스레드 실행
사용법
1. AsyncConfig.java 생성
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer { // 추가
private int CORE_POOL_SIZE = 2;
private int MAX_POOL_SIZE = 10;
private int QUEUE_CAPACITY = 100_000;
@Bean(name = "dashBoardExecutor")
public Executor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize( CORE_POOL_SIZE );
taskExecutor.setMaxPoolSize( MAX_POOL_SIZE );
taskExecutor.setQueueCapacity( QUEUE_CAPACITY );
taskExecutor.setTaskDecorator( new CustomDecorator() ); // 데코레이터 적용
taskExecutor.setThreadNamePrefix( "BoardExecutor-" );
taskExecutor.setRejectedExecutionHandler( new ThreadPoolExecutor.CallerRunsPolicy() );
return taskExecutor;
}
// override method
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler(); // 추가
}
}
2. 메서드에 @Async 추가
@Async("dashBoardExecutor")
public CompletableFuture<List<AwsAssetsVo>> getAllResource(long providerId) {
//
//내부 로직
//
return CompletableFuture.completedFuture(awsAssets);
}
TroubleShooting
문제 : 아래와 같이 코드를 사용했을 경우 정상적으로 멀티스레드 구동 되지 않음
원인 : 로직 실행 후 .join() 하는 구문이 있을 경우 다중 실행 X
@GetMapping("/--- 예시 내용---") public ResponseVo getAllAssetData(@PathVariable long 무언가) { CompletableFuture<List<AwsAssetsVo>> threadAwsAssetsVo = dashboardUserService.getAllResource(providerId); List<AwsAssetsVo> awsAssetsVoList = threadAwsAssetsVo.join(); CompletableFuture<UpdatedResourceVo> threadUpdatedResourceVo = dashboardUserService.getUpdatedResource(providerId); UpdatedResourceVo updatedResourceVo = threadUpdatedResourceVo.join(); AssetDataVo assetData = AssetDataVo.builder() .awsAssetsVo(awsAssetsVoList) .updatedResourceVo(updatedResourceVo) .build(); ResponseVo result = new ResponseVo(); result.setResult(assetData); return ok(result); }
결과 : 코드 수정 및 제네릭 사용하여 공통으로 메서드 구현
@GetMapping("/--- 예시 내용---") public ResponseVo getAllAssetData(@PathVariable long 무언가) { List<AwsAssetsVo> awsAssetsVoList = joinCompletableFuture(dashboardUserService.getAllResource(providerId)); UpdatedResourceVo updatedResourceVo = joinCompletableFuture(dashboardUserService.getUpdatedResource(providerId)); AssetDataVo assetData = AssetDataVo.builder() .awsAssetsVo(awsAssetsVoList) .updatedResourceVo(updatedResourceVo) .build(); ResponseVo result = new ResponseVo(); result.setResult(assetData); return ok(result); }
private static
return completableFuture.join();
}
## 참고 링크
- 구현 시 참고한 링크 : https://cano721.tistory.com/208#Return_%EA%B0%92%EC%9D%B4_%ED%95%84%EC%9A%94%ED%95%A0%EB%95%8C
## 2023.07.06 추가
- CORE_POOL_SIZE : 처음에 이게 CPU 사이즈를 입력하는거라고 생각. 그게 아니라 기본 생성 thread의 Pool size를 설정해주는 옵션임.
'Language > Java' 카테고리의 다른 글
Spring REST Docs + Swagger UI (0) | 2024.02.29 |
---|---|
Spring 에서 배치 프로그램 사용해보기 (0) | 2024.02.27 |
JDK21의 신기능 Virtual Thread 알아보기(카카오 테크 밋업) (0) | 2024.02.26 |
[객체 리스트 정렬] 내림 차순으로 정렬하기 (0) | 2023.09.25 |
[JAVA 개념공부] List와 ArrayList의 차이 (0) | 2021.10.25 |