ExecutorService excutor = Excutors.newFixedThreadPool(50);
...
executor.submit(()->pushClient.sendPush(pushData));
- 스프링에서는
@Async로 간편히 비동기 실행이 가능
- 특정 메서드를 저 애너테이션을 붙이면 비동기 실행이되는 식
public class PushService{
@Async
public void sendPushAsync(Pushdata pushData){
pushClient.sendPush...
}
}
- !!! 비동기로 동작되는 메서드가 try-catch 내부에 있어도 익센션발생해도 catch가 발동 안된다 !!!
- catch는 한 스레드기준인듯?
- 트랜잭션 범위 안에서 비동기 코드를 실행할 때는 트랜잭션 연동 여부에 주의
- 멀티 스레드로 메서드 실행 시, 연동 과정에서 발생한 오류 처리에 더 신경써야함
- 예외을 전파해도 소용이 없기 때문
- 멀티 스레드로 실행되는 코드는 내부에서 연동 과정에서 발생한 오류를 직접 처리해야한다
//비동기로 실행되는 코드는
//연동 과정에서 발생되는 오류 직접 처리
public class PushService{
@Async
public void sendPushAsync(Pushdata pushData){
try{
pushClient.sendPush...
}catch(Exception e){
try{
Tread.sleep(500);
}
catch(Exception ex){}
try{
pushClient.sendPush(pushData)// 재시도
}
catch(Exception e1){
//실패로그남기거나
}
}
}
}
스레드와 메모리
- 비동기로 실행할 코드가 외부 API 호출이나 DB 연동 같이 네트워크 IO 작업이라면 가상 스레드, Go의 고루틴 등을 쓰는것도 방법
- 가상 스레드나 고루틴은 실제 네이티브 스레드가 아닌 런타임에서 관리하는 경량 스레드로 적은 메모리를 씀
- 사용하는 메모리 적은 만큼 한 번에 만들 수 있는 스레드 개수도 많다.