비동기 처리란?
특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고
순차적으로 다음 코드를 먼저 실행
@async
1. public 메소드에만 작동한다. (private 메소드는 비동기로 작동하지 않는다)
2. 셀프 호출(같은 클래스 안에서 Async메소드를 호출하면 작동하지 않음)
package com.example.async;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class AsyncApplication {
public static void main(String[] args) {
SpringApplication.run(AsyncApplication.class, args);
}
}
package com.example.async.controller;
import com.example.async.service.AsyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.CompletableFuture;
@Slf4j
@RestController
@RequestMapping("/api")
public class ApiController {
private final AsyncService asyncService;
public ApiController(AsyncService asyncService) {
this.asyncService = asyncService;
}
@GetMapping("/hello")
public CompletableFuture hello(){ //CompletableFuture 다른 스레드에서 실행을 시키고 결과를 반환받는 형태
log.info("Completable Future init");
return asyncService.run();
}
}
package com.example.async.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
@Slf4j
@Service
public class AsyncService {
@Async("async-thread")
public CompletableFuture run() {
return new AsyncResult(hello()).completable();
}
public String hello() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(2000);
log.info("thread sleep....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "async hello";
}
}
package com.example.async.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
public class AppConfig {
@Bean("async-thread")
public Executor asyncThread(){
ThreadPoolTaskExecutor ThreadPoolTaskExecutor = new ThreadPoolTaskExecutor();
ThreadPoolTaskExecutor.setMaxPoolSize(100);
ThreadPoolTaskExecutor.setCorePoolSize(10); //1.여기 10개가 차면 3.10개만 큼 늘어남
ThreadPoolTaskExecutor.setQueueCapacity(10); //2.큐에 10개가 들어가고 4.20개 다 차면 또 여기로 옴
ThreadPoolTaskExecutor.setThreadNamePrefix("Async-");
return ThreadPoolTaskExecutor;
}
}