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의 고루틴 등을 쓰는것도 방법이다. 가상 스레드가 고루틴은 실제 네이티브 스레드가 아닌 런타임에서 관리하는 경량 스레드로 적은 메모리를 쓴다.

사용하는 메모리 적은 만큼 한 번에 만들 수 있는 스레드 개수도 많다.