백엔드 개발자는 프로그램의 로직에 대해 고민한다.
어떻게하면 더 효율적이고 같은 메모리를 점유하며 더 빠르게 동작시킬 수 있는지
반대로 같은 속도에서 더 작은 메모리를 사용하게 하려면 어떻게 해야하는지.
그 중 빈번하게 나오는 개념이 동기와 비동기의 개념이다.
동기와 비동기의 특징, 차이점과 연관되는 궁금증들을 고민해본다.
동기와 비동기는 그리 어려운 개념이 아니다.
동기로 호출한다, 비동기로 호출한다 에서 호출하는 함수의 작업 완료를 기다리느냐 마느냐의 차이로 동기, 비동기가 나뉜다.
예를 들어 함수 A, 함수 B가 있다고 가정한다.
함수 A가 동기로 함수 B를 호출한다고 하면 함수 A는 함수 B의 작업이 완료 될때까지 기다린 이후에 실행된다.
그렇기 때문에 B 이후 A가 순차적으로 실행된다는 점을 보장할 수 있게된다.
반대로 비동기로 호출을 하게되면 함수 A는 함수 B의 작업 완료의 유무와 상관없이 본인의 동작을 수행하게되고 순차적으로 진행되지 않는다.
그렇다면 함수 B가 작업완료를 할때까지 함수 A가 동작을 멈추는 부분이 블로킹과 비슷하게 보이는데 이 둘의 차이는 뭘까?
우선 앞서말한대로 동기 호출에서는 호출된 함수가 작업을 완료할때까지 호출한 함수가 기다리게 된다.
블로킹은 함수가 호출된 후, 호출한 함수의 결과를 기다리기 위해 실행을 멈추는 상태를 말한다.
즉, 제어권이 반환되지 않고 그냥 기다리는 상태 인 것이다.
나는 java, Springboot 환경에서 개발을 하므로 이에 맞춰 설명한다.
스프링에서는 @Async 어노테이션을 사용해서 비동기처리를 수행할 수 있다.
어노테이션을 이용해 쉽게 적용할 수 있지만 이 어노테이션은 주의해야할 점이 존재한다.
1. 기본적으로 @Async 가 적용된 메소드에서 발생하는 예외는 호출자에게 전파되지 않는다.
이와 같은 특징으로 비동기 메소드에서 예외를 정상적으로 처리하기위해서는 비동기 예외 처리를 따로 해주어야 한다.
2. @Async 어노테이션은 프록시 기반으로 동작한다.
프록시 : 어떤 객체의 대리자. 원본 객체에 대한 접근을 가로채거나 추가적인 기능 수행
프록시 기반으로 동작이 수행되므로 같은 클래스 내부에서 직접 호출하는 경우 별도의 스레드에서 메소드가 실행되지 않는다.
@Async 어노테이션을 사용하게되면 메소드는 별도의 스레드에서 비동기적으로 실행된다.
면접 질문 내용과 답변의 일부는 기술 면접 구독 서비스 - 매일메일 에 있다.
흥미로웠다면 구독해보는 것도 추천한다!