๊ฐ์
๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ์ค๋๋ ์ ์ํํธ์จ์ด ๊ฐ๋ฐ์์ ๋งค์ฐ ์ค์ํ ๊ฐ๋ ์ ๋๋ค. ๋์ฉ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ, ๋๋ฆฐ I/O ์์ , ๋ณต์กํ ๊ณ์ฐ ๋ฑ ๋ค์ํ ์์ ์ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ๋ฉด์ ์์คํ ์ ์๋ต ์๊ฐ์ ๊ฐ์ ํ๊ณ , ๋ฆฌ์์ค๋ฅผ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ๋๋ฐ ๋์์ด ๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
์คํ๋ง์์๋ @Async ์ด๋ ธํ ์ด์ ์ ํตํด ์ด๋ฌํ ๋น๋๊ธฐ ๋ฉ์๋๋ฅผ ๊ฐ๋จํ๊ฒ ์คํํ ์ ์๋๋ฐ, ์ด๋ฌํ @Async ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ ๋ ์ฃผ์ํด์ผ ํ ์ฌ๋ฌ ๊ฐ์ง ์ฌํญ์ ๋ํด์ ์ ๋ฆฌํด ๋ณด๊ฒ ์ต๋๋ค.
์ฃผ์์
- Exception Handling
- ๋ฉ์๋ ํธ์ถ
- ๋ฆฌํด ํ์
- ํธ๋์ญ์ ๊ด๋ฆฌ
- Execution
Exception Handling
๊ธฐ๋ณธ์ ์ผ๋ก @Async ๋ฉ์๋์์ ๋ฐ์ํ๋ ์์ธ๋ ํธ์ถ์์๊ฒ ์ ํ๊ฐ ๋์ง ์์ต๋๋ค. ์ด๋ @Async ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ๋ฉ์๋๊ฐ ๋ณ๋์ ์ค๋ ๋์์ ์คํ๋๋ฏ๋ก ๋ฉ์ธ ์ค๋ ๋์์ ์บ์น๋ฅผ ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด์๋ AsyncUncaughtExceptionHandler๋ฅผ ์ฌ์ฉํ์ฌ ์์ธ๋ฅผ ์ ์ ํ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
AsyncConfigurerSupport๋ฅผ ์์๋ฐ๋ ํด๋์ค
@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new MyAsyncUncaughtExceptionHandler();
}
}
AsyncUncaughtExceptionHandler๋ฅผ ๊ตฌํํ๋ ํด๋์ค
public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
System.out.println("Exception message - " + throwable.getMessage());
System.out.println("Method name - " + method.getName());
for (Object param : obj) {
System.out.println("Parameter value - " + param);
}
}
}
์์ ๊ฐ์ด AsyncConfigurerSupport๋ฅผ ์์๋ฐ๊ณ , getAsyncUncaughtExceptionHandler()๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ์ฌ ์ฌ์ฉ์๊ฐ ์ ํ ์์ธ ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ฉ์๋ ํธ์ถ
@Service
public class xxxService {
public void internalCall() {
this.asyncMethod(); // ๋๊ธฐ์ ์ผ๋ก ์คํ๋จ
}
@Async
public void asyncMethod() {
// ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌ๋์ด์ผ ํ๋ ๋ก์ง
}
}
์ ์ฝ๋์ฒ๋ผ ์คํ๋ง์์ @Async ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ๋ฉ์๋๋ ๊ฐ์ ํด๋์ค ๋ด๋ถ์์ ์ง์ ํธ์ถํ ๊ฒฝ์ฐ, ๋ณ๋์ ์ค๋ ๋์์ ์คํ๋์ง ์์ต๋๋ค. ์ด๋ ์คํ๋ง์ AOP๊ฐ ํ๋ก์ ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ๋ณ๋์ ๋น์ ์์ฑํ๊ฑฐ๋, ๋ค๋ฅธ ํด๋์ค์์ ํธ์ถํด์ผ ํ๋ฉฐ ๊ฐ์ ํด๋์ค์์ ํธ์ถํ๋ ค๋ฉด ์๋์ฒ๋ผ self reference๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
@Service
public class SelfInvocationService {
@Autowired
private SelfInvocationService self;
public void method() {
self.asyncMethod(); // self-invocation์ผ๋ก ๋น๋๊ธฐ์ ์ผ๋ก ์คํ๋จ
}
@Async
public void asyncMethod() {
// ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌ๋์ด์ผ ํ๋ ๋ก์ง
}
}
์ ์ฝ๋์์ method()๋ self.asyncMethod();๋ฅผ ํตํด ๋น๋๊ธฐ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ์์ต๋๋ค. self๋ SelfInvocationService์ ์ธ์คํด์ค๋ก, ์คํ๋ง ์ปจํ ์ด๋์ ์ํด ํ๋ก์๊ฐ ์ฃผ์ ๋ฉ๋๋ค. ์ด๋ ๊ฒ ๋๋ฉด asyncMethod()๊ฐ ๋น๋๊ธฐ์ ์ผ๋ก ์คํ๋ฉ๋๋ค.
๋ฆฌํด ํ์
@Async ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ๋ฉ์๋๋ void, Future, CompletableFuture ์ด ์ค ํ๋์ ๋ฐํ ํ์ ์ ๊ฐ์ ธ์ผ ํฉ๋๋ค. ๋ง์ฝ Future๋ฅผ ๋ฐํํ๋ ๊ฒฝ์ฐ, ๋น๋๊ธฐ ์์ ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๊ณ ํด๋น ์์ ์ ์๋ฃ๋ฅผ ๋๊ธฐํ ์ ์์ต๋๋ค. ์๋ ์ฝ๋๋ ์ด๋ฅผ ๋ณด์ฌ์ฃผ๋ ์์์ ๋๋ค.
@Service
public class AsyncService {
@Async
public Future<String> asyncMethodWithReturnType() {
System.out.println("Execute method asynchronously - " + Thread.currentThread().getName());
try {
Thread.sleep(5000);
return new AsyncResult<>("hello world !!!!");
} catch (final InterruptedException e) {
}
return null;
}
}
์์ ๋ฉ์๋๋ ๋น๋๊ธฐ์ ์ผ๋ก ์คํ๋๋ฉฐ, ์์ ์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ฆ์ Future ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด Future๊ฐ์ฒด๋ฅผ ํตํด ๋น๋๊ธฐ ์์ ์ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ Future๋ CompletableFuture ๊ฐ์ฒด๋ฅผ ๋ฐํ๋ฐ์๋, ๋น๋๊ธฐ ์ฐ์ฐ์ด ์์ง ์๋ฃ๋์ง ์์์ ๊ฒฝ์ฐ ๋ฐํ๊ฐ์ ์ค์ ๊ฐ๋ค์ ๋ด๊ธฐ์ง ์์์ ์๋ ์์ต๋๋ค.
@Service
public class xxxService {
@Autowired
private AsyncService asyncService;
public void method() {
Future<String> future = asyncService.asyncMethodWithReturnType();
String result = future.get(); // This will block
System.out.println(result);
}
}
ํด๊ฒฐ ๋ฐฉ๋ฒ์ผ๋ก๋ ์์ ๊ฐ์ด Future์ get() ๋ฉ์๋๋ฅผ ํตํด ๋น๋๊ธฐ ์์ ์ด ๋๋ ๋๊น์ง(๊ฐ์ด ๋ด๊ธธ ๋๊น์ง) ํ์ฌ ์ค๋ ๋๋ฅผ ๋ธ๋กํนํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ํ์ง๋ง ์ด๋ ๋น๋๊ธฐ ๋ฉ์๋๋ฅผ ๋๊ธฐ์ ์ผ๋ก ๋์ํ๊ฒ ๋ง๋ค์ด, ์๋ ๋น๋๊ธฐ๋ก ์ค๊ณ๋ ์ฝ๋์ ์ด์ ์ ๋๋ฆฌ์ง ๋ชปํ๊ฒ ๋ฉ๋๋ค.
๋ฐ๋ผ์ Future๋ CompletableFuture์ ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํ ๋๋ ์ฃผ์๊ฐ ํ์ํ๋ฐ, ๊ฐ๋ฅํ๋ฉด non-blocking ๋ฐฉ์์ผ๋ก ์ ๊ทผํ๊ฑฐ๋ ํ์ํ ๊ฒฝ์ฐ ์ฝ๋ฐฑ์ ์ฌ์ฉํ์ฌ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ CompletableFuture์ thenApply, thenAccept ๋ฑ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํํ ์ ์์ผ๋ฉฐ, ์ด๋ ๊ฒ ํ๋ฉด ๋น๋๊ธฐ ์ฐ์ฐ ๊ฒฐ๊ด๊ฐ์ด ๋ด๊ฒผ์ ๋ ๋น๋๊ธฐ์ ์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
ํธ๋์ญ์ ๊ด๋ฆฌ
๋น๋๊ธฐ ๋ฉ์๋์์ ํธ๋์ญ์ ์ ์ฌ์ฉํ ๋๋ ์ฃผ์๊ฐ ํ์ํฉ๋๋ค. @Async ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ๋ฉ์๋๋ ํธ์ถํ ๋ฉ์๋์ ๋ ๋ฆฝ์ ์ธ ์ค๋ ๋์์ ๋์ํ๊ธฐ ๋๋ฌธ์, ๋น๋๊ธฐ ๋ฉ์๋ ๋ด์์ ์์ฑ๋ ํธ๋์ญ์ ์ ํธ์ถํ ๋ฉ์๋์ ํธ๋์ญ์ ๊ณผ๋ ๋ณ๊ฐ์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ์ง๋๋ค.
์ฆ ๋น๋๊ธฐ ๋ฉ์๋ ๋ด์์ ์์ธ๊ฐ ๋ฐ์ํ์ฌ ํธ๋์ญ์ ์ด ๋กค๋ฐฑ๋์ด์ผ ํ ๊ฒฝ์ฐ์๋, ์ด๋ ํด๋น ํธ๋์ญ์ ์ ์์ฑํ ๋ณ๋์ ์ค๋ ๋์์ ๋ ๋ฆฝ์ ์ผ๋ก ์ฒ๋ฆฌ๋๋ฏ๋ก, ์๋์ ํธ์ถ ๋ฉ์๋์ ํธ๋์ญ์ ์๋ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.
@Service
public class TransactionalService {
@Autowired
private AsyncService asyncService;
@Transactional
public void transactionalMethod() {
asyncService.asyncMethodWithNewTransaction();
}
}
์ ์ฝ๋์์, transactionalMethod()๋ @Transactional ์ด๋ ธํ ์ด์ ์ด ๋ถ์ด ํธ๋์ญ์ ๋ฒ์ ๋ด์์ ์คํ๋์ง๋ง, asyncMethodWithNewTransaction()์ @Async ์ด๋ ธํ ์ด์ ์ด ๋ถ์ด ์๋ก์ด ์ค๋ ๋์์ ์คํ๋๋ฏ๋ก ๋ณ๋์ ํธ๋์ญ์ ์ ์์ฑํฉ๋๋ค.
๋ฐ๋ผ์ asyncMethodWithNewTransaction()์์ ์์ธ๊ฐ ๋ฐ์ํ์ฌ ๋กค๋ฐฑ์ด ํ์ํ๋๋ผ๋, ์ด๋ asyncMethodWithNewTransaction()๋ฅผ ์คํํ๋ ๋ณ๋์ ์ค๋ ๋์์ ์ฒ๋ฆฌ๋๋ฏ๋ก transactionalMethod()์ ํธ๋์ญ์ ์๋ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.
Executor
์คํ๋ง์์ ๋น๋๊ธฐ ์์ ์ ์ํํ๋ ค๋ฉด ๋ณดํต @EnableAsync ์ด๋ ธํ ์ด์ ๊ณผ @Async๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ ๊ฒ ์ค์ ํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก SimpleAsyncTaskExecutor๊ฐ ์ฌ์ฉ๋๋๋ฐ, ์ด๋ ๋น๋๊ธฐ ์์ ๋ง๋ค ์๋ก์ด ์ค๋ ๋๋ฅผ ์์ฑํ๋ ์ค๋ ๋ํ์ ๋๋ค. ์ด๋ก ์ธํด ๋ฆฌ์์ค ๋ญ๋น, ์ฑ๋ฅ ์ ํ, ์ค์ผ์ผ๋ง ๋ฌธ์ ๋ฑ์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
- ๋ฆฌ์์ค ๋ญ๋น: ๊ฐ ๋น๋๊ธฐ ์์ ๋ง๋ค ์๋ก์ด ์ค๋ ๋๋ฅผ ์์ฑํ๋ฏ๋ก, ๋์์ ๋ง์ ๋น๋๊ธฐ ์์ ์ด ์์ฒญ๋๋ฉด ๋งค๋ฒ ๋ง์ ์ค๋ ๋๊ฐ ์์ฑ๋๋ค. ๋ฐ๋ผ์ CPU์ ๋ฉ๋ชจ๋ฆฌ ๋ฆฌ์์ค์ ์ฌ์ฉ๋์ด ๊ณผ๋ํ๊ฒ ์ฆ๊ฐํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
- ์ฑ๋ฅ ์ ํ: ์ค๋ ๋๋ฅผ ์์ฑํ๊ณ ์๋ฉธ์ํค๋ ๋ฐ๋ ๋ง์ ์๊ฐ๊ณผ ๋ฆฌ์์ค๊ฐ ์์๋๋ค. ๊ฐ ์์ ๋ง๋ค ์ค๋ ๋๋ฅผ ์์ฑํ๋ฉด ์ด๋ฐ ์ค๋ฒํค๋๊ฐ ๊ณ์ ๋ฐ์ํ๊ฒ ๋๊ณ , ์ ์ฒด์ ์ธ ์์คํ ์ฑ๋ฅ์ ์ํฅ์ ๋ผ์น ์ ์๋ค.
- ์ค์ผ์ผ๋ง ๋ฌธ์ : SimpleAsyncTaskExecutor๋ ์ค๋ ๋ ์์ ๋ํ ์ ํ์ด ์๋ค. ๋ฐ๋ผ์ ๋์์ ๋ง์ ์์ฒญ์ด ๋ค์ด์ฌ ๊ฒฝ์ฐ ์ค๋ ๋ ์๊ฐ ๋ฌดํ์ ์ผ๋ก ์ ์ดํ ์ ์๋ ์์ค์ผ๋ก ์ฆ๊ฐํ ์ ์์ผ๋ฉฐ, ์ด๋ ๊ณง OutOfMemoryError ๋ฑ์ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์๋ค.
์ด๋ฌํ ์ด์ ๋ก, ํน๋ณํ ๊ฒฝ์ฐ๊ฐ ์๋๋ผ๋ฉด SimpleAsyncTaskExecutor ๋ณด๋ค๋ ThreadPoolTaskExecutor ๊ฐ์ ์ ํ๋ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๋ ์ค๋ ๋ํ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
ThreadPoolTaskExecutor๋ Java์ ThreadPoolExecutor๋ฅผ Wrapping ํ ๊ฒ์ผ๋ก, ์คํ๋ง์์ ์ ๊ณตํ๋ TaskExecutor ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด์ ๋๋ค. Executor๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์๋ ์๋์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
- Bean์ผ๋ก ์ ์
- AsyncConfigurerSupport๋ฅผ ์์๋ฐ์ getAsyncExecutor()๋ฅผ ์ฌ์ ์
1. ์ง์ Bean์ผ๋ก Executor๋ฅผ ์ ์
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean(name = "threadPoolTaskExecutor")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("Executor-");
executor.initialize();
return executor;
}
}
๊ฐ๊ฐ์ ์ต์ ์ค์ ์ ๋ํ ์ค๋ช ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- setCorePoolSize
- ์ค๋ ๋ ํ์ด ์คํ์ ์์ํ ๋ ์์ฑ๋๋ ์ค๋ ๋์ ์๋ฅผ ์ ์ํ๋ฉฐ, ์ค๋ ๋ ํ์ ๊ธฐ๋ณธ ์ฌ์ด์ฆ๋ฅผ ์ค์ ํฉ๋๋ค.
- ์ค๋ ๋ ํ์ ์์
์ด ๋ค์ด์ค๊ธฐ ์์ํ๋ฉด
์ฆ์ corePoolSize๋งํผ์ ์ค๋ ๋๋ฅผ ์์ฑํ๊ณํ์ํ ๋งํผ ์์ฑํ๊ณ https://dkswnkk.tistory.com/745), ์ค๋ ๋๋ค์ ์ค๋ ๋ ํ์ด ์์ ์ ๋ฐ์ ๋๊น์ง ๋๊ธฐ ์ํ๋ก ์ ์ง๋ฉ๋๋ค. ๋ง์ฝ ๋ชจ๋ core ์ค๋ ๋๊ฐ ์์ ์ ์ฒ๋ฆฌํ๊ณ ์๊ณ ์ถ๊ฐ ์์ ์ด ๋ค์ด์จ ๊ฒฝ์ฐ, ์์ ์ ํ์ ๋ฐฐ์น๋๊ฑฐ๋ maxPoolSize๊น์ง ์ค๋ ๋๊ฐ ์ถ๊ฐ๋ก ์์ฑ๋ฉ๋๋ค.
- setMaxPoolSize
- ์ค๋ ๋ ํ์ด ํ์ฅ๋ ์ ์๋ ์ค๋ ๋์ ์ํ์ ์ ์ค์ ํ๋ฉฐ, ์ค๋ ๋ ํ์ด ๊ด๋ฆฌํ ์ ์๋ ์ต๋ ์ค๋ ๋ ์๋ฅผ ์ ์ํฉ๋๋ค. ๋ง์ฝ corePoolSize๋ฅผ ์ด๊ณผํ๋ ์์ ์ด ๋ค์ด์ฌ ๊ฒฝ์ฐ, ์ด๋ฌํ ์ถ๊ฐ ์์ ๋ค์ ๋จผ์ ํ์ ๋ฐฐ์น๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ๋๊ธฐ์ด์ด ๊ฐ๋ ์ฐจ๋ฉด ์ค๋ ๋ ํ์ maxPoolSize์ ๋๋ฌํ ๋๊น์ง ์ถ๊ฐ ์ค๋ ๋๋ฅผ ์์ฑํ์ฌ ์์ ์ ์ฒ๋ฆฌํฉ๋๋ค.
- maxPoolSize์ ๋๋ฌํ๋ฉด ์ค๋ ๋ ํ์ ์ ์์ ์ ๋ฐ์๋ค์ด์ง ์์ผ๋ฉฐ, ๋์ ์ ์ฑ ์ ๋ฐ๋ผ ๊ฑฐ๋ถํ๊ฑฐ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
- setQueueCapacity
- corePoolSize๊ฐ ๊ฐ๋ ์ฐฌ ์ํ์์ ์ถ๊ฐ ์์ ์ ์ฒ๋ฆฌํ ์ ์์ ๋ ๋๊ธฐํ๋ ์์ ์ ์ต๋ ๊ฐ์๋ฅผ ์ ์ํ๋ฉฐ, ์ค๋ ๋ ํ์ ์์ ๋๊ธฐ์ด ํฌ๊ธฐ๋ฅผ ์ค์ ํฉ๋๋ค.
- ์์ ๋๊ธฐ์ด์ corePoolSize์ ์๋ ์ค๋ ๋๋ค์ด ๋ชจ๋ ์ฌ์ฉ ์ค์ผ ๋ ์ถ๊ฐ ์์ ์ ์์ ์ ์ฅํ๋ ๊ณต๊ฐ์ ๋๋ค. ๋๊ธฐ์ด์ ํฌ๊ธฐ๊ฐ ๊ฝ ์ฐจ๋ฉด, ์ค๋ ๋ ํ์ maxPoolSize๊น์ง ์ค๋ ๋๋ฅผ ์์ฑํ์ฌ ๋๊ธฐ์ด์ ์๋ ์์ ์ ์ฒ๋ฆฌํ๊ธฐ ์์ํฉ๋๋ค. ๋๊ธฐ์ด์ด ๊ฐ๋ ์ฐจ๊ณ maxPoolSize์ ๋๋ฌํ๋ฉด ์ค๋ ๋ ํ์ ์๋ก์ด ์์ ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง ๊ฒฐ์ ํด์ผ ํ๋ฉฐ, ์ผ๋ฐ์ ์ผ๋ก ๊ฑฐ๋ถ ์ ์ฑ (RejectedExecutionHandler)์ ์ฌ์ฉํ์ฌ ์ถ๊ฐ ์์ ์ ์ฒ๋ฆฌํฉ๋๋ค.
- setThreadNamePrefix
- ์์ฑ๋๋ ์ค๋ ๋์ ์ด๋ฆ ์ ๋์ฌ๋ฅผ ์ ์ํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋๋ฒ๊น ์ด๋ ๋ก๊น ์์ ์ด๋ค ์ค๋ ๋๊ฐ ์์ ์ ์ฒ๋ฆฌํ๊ณ ์๋์ง ์ฝ๊ฒ ์๋ณํ ์ ์๋๋ฐ, ํ์ฌ ์์์ฒ๋ผ ์์ฑํ๋ฉด ๊ฐ ์ค๋ ๋์ ์ด๋ฆ์ด Executor-1, Executor-2์ ๊ฐ์ด ์ค์ ๋ฉ๋๋ค.
- initialize()
- ์ค๋ ๋ ํ์ ์ด๊ธฐํํฉ๋๋ค. initialize()๊ฐ ํธ์ถ๋๋ฉด, ์ค์ ๋ corePoolSize๋งํผ์ ์ค๋ ๋๊ฐ ์ฆ์ ์์ฑ๋ฉ๋๋ค.
์ด๋ ๊ฒ ์ค์ ํ ํ, @Async ์ด๋ ธํ ์ด์ ์ ์๋์ฒ๋ผ Executor์ Bean ์ด๋ฆ์ ์ธ์๋ก ์ ๋ฌํ๋ฉด ๋ฉ๋๋ค.
@Service
public class xxxService {
@Async("threadPoolTaskExecutor")
public void asyncMethod() {
// ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌ๋์ด์ผ ํ๋ ๋ก์ง
}
}
์ด ๋ฐฉ๋ฒ์ ThreadPoolTaskExecutor๋ฅผ ์ง์ Bean์ผ๋ก ๋ฑ๋กํฉ๋๋ค. ๋ฐ๋ผ์ @Async ์ด๋ ธํ ์ด์ ์ Bean ์ด๋ฆ์ ์ง์ ์ง์ ํด์ค ์ ์์ต๋๋ค. ์ด ๋ฐฉ์์ ์ฅ์ ์ ์ฌ๋ฌ ๊ฐ์ Executor๋ฅผ ๊ฐ๊ฐ Bean์ผ๋ก ๋ฑ๋กํ๊ณ , ์ํฉ์ ๋ง๊ฒ ์ ์ ํ Executor๋ฅผ ์ ํํ ์ ์๋ค๋ ์ ์ ๋๋ค. ์ฆ, ๋น๋๊ธฐ ์์ ์ ์ข ๋ฅ๋ ๋ณต์ก๋์ ๋ฐ๋ผ ๋ค๋ฅธ Executor๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์์
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean(name = "threadPoolTaskExecutor")
public Executor threadPoolTaskExecutor() {
//...
}
@Bean(name = "anotherExecutor")
public Executor anotherExecutor() {
//...
}
}
@Service
public class xxxService {
@Async("threadPoolTaskExecutor")
public void asyncMethod() {
// ๋ก์ง
}
@Async("anotherExecutor")
public void anotherAsyncMethod() {
// ๋ค๋ฅธ ๋ก์ง
}
}
2. AsyncConfigurerSupport๋ฅผ ์์๋ฐ์ getAsyncExecutor()๋ฅผ ์ฌ์ ์
@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("Executor-");
executor.initialize();
return executor;
}
}
์ด ๋ฐฉ๋ฒ์ ์คํ๋ง์ ๊ธฐ๋ณธ Executor๋ฅผ ์ฌ์ ์ํ์ฌ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ผ๋ก, ๋ณ๋์ ์ด๋ฆ์ ์ง์ ํ์ง ์์๋ ๋ฉ๋๋ค. ์ด ๋ฐฉ์์ ์ ์ญ์ ์ธ Executor ์ค์ ์ ์ ์ฉํ๋ฉฐ, ํ๋ก์ ํธ ์ ์ฒด์์ ๋จ์ผ Executor๋ฅผ ์ฌ์ฉํ๋ ค๋ ๊ฒฝ์ฐ์ ์ ํฉํฉ๋๋ค.
์์
@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//...
return executor;
}
}
@Service
public class xxxService {
@Async
public void asyncMethod() {
// ๋ก์ง
}
}
๋ฐ๋ผ์, ์ด๋ค ๋ฐฉ๋ฒ์ ์ ํํ ์ง๋ ๋น์ฆ๋์ค ๋ก์ง์ ์๊ตฌ ์ฌํญ๊ณผ ํ๋ก์ ํธ์ ๊ท๋ชจ์ ๋ฐ๋ผ ๊ฒฐ์ ํ๋ฉด ๋ฉ๋๋ค.
'BackEnd๐ฑ > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Spring Data Redis์ @Indexed ์ฌ์ฉ ์ ์ฃผ์์ (0) | 2023.08.07 |
---|---|
WebClient์์ ์๋ฌ ์ฒ๋ฆฌ์ ์ฌ์๋ํ๋ ๋ฐฉ๋ฒ (0) | 2023.08.03 |
Spring Batch๋? ๊ฐ๋จํ ๊ฐ๋ ๊ณผ ์ฝ๋ ์ดํด๋ณด๊ธฐ (0) | 2023.07.29 |
Kafka ๊ฐ๋ ๊ณผ Spring Boot + Kafka ๊ฐ๋จํ ์ฐ๋ (1) | 2023.07.19 |
์คํ๋ง ์ด๋ฒคํธ ๋ฐํ๊ณผ ๊ตฌ๋ ์ผ๋ก ํธ๋์ญ์ ๋ถ๋ฆฌํ๊ธฐ (1) | 2023.07.09 |
SSE๋ก ์๋ฆผ ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ with Spring (7) | 2023.06.18 |
๋๊ธ