비동기 처리
부족한 부분이 많아 다시 공부해봐야할 듯 하다.
다음은 annotation을 통해 제일 기본적으로 동작하는 async 코드이다.
@Slf4j
@RestController
@RequestMapping("/async")
public class AsyncApiController {
private final AsyncService asyncService;
public AsyncApiController(AsyncService asyncService) {
this.asyncService = asyncService;
}
@GetMapping("/hello")
public String hello(){
// asyncService.hello() 메서드가 비동기처리되어 있기 때문에
// hello() 메서드도 병렬처리되서 각각 다른 thread에서 동작함
asyncService.hello();
log.info("method end");
return "hello";
}
}
@Slf4j
@Service
public class AsyncService {
@Async
public void hello() {
for (int i=0 ; i<10 ; i++){
try {
Thread.sleep(2000);
log.info("Thread sleep...");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
@Slf4j
@RestController
@RequestMapping("/async")
public class AsyncApiController {
private final AsyncService asyncService;
public AsyncApiController(AsyncService asyncService) {
this.asyncService = asyncService;
}
@GetMapping("/hello")
public CompletableFuture hello(){
log.info("completable future init");
return asyncService.run();
}
}
@Slf4j
@Service
public class AsyncService {
// CompletableFuture는 다수 개의 api를 동시에 전송받아서 join한 다음
// 거기에 대한 결과를 모아서 return 할 때 쓰는게 좋음
// 그러나 해당 코드방식은 spring에서 정한 thread를 사용(8개 thread가 default)
@Async("async-thread") // "async-thread" : 직접 설정한 thread
public CompletableFuture run(){
// hello();를 호출해도 한 클래스에 존재하는 메서드는 async를 타지 않음
return new AsyncResult(hello()).completable();
}// Async는 AOP기반이기 때문에 proxy 패턴을 타서 public 메서드에만 사용할 수 있음
public String hello() {
for (int i=0 ; i<10 ; i++){
try {
Thread.sleep(2000);
log.info("Thread sleep...");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return "async hello";
}
}
@Configuration
public class AppConfig {
@Bean("async-thread")
public Executor asyncThread(){
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
// 추가로 threadPool 다루는 방법 찾아보기
threadPoolTaskExecutor.setMaxPoolSize(100);
threadPoolTaskExecutor.setCorePoolSize(10);
threadPoolTaskExecutor.setQueueCapacity(10);
threadPoolTaskExecutor.setThreadNamePrefix("Async-");
return threadPoolTaskExecutor;
}
}
출처 : 한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online.