동기와 비동기 방식의 차이에 대한 쉬운 예시로 카페에서 커피를 주문할 때를 생각해 볼 수 있다. 사람들이 줄 지어 주문을 하려고 카운터 앞에 서 있을 때, 한 명에게 주문을 받고 커피를 전달한 후에 다음 사람의 주문을 받는 건 동기 방식이다. 반면에 일단 주문을 연속적으로 받고 커피 전달은 다른 곳에서 제조 되는대로 담당 하는 건 비동기 방식이다.
그렇다면 언제나 비동기 방식이 효율적인 걸까? 이 카페에서 주문한 음료 수만큼 쿠폰 스탬프를 찍어준다고 생각해보자. 아직 주문을 안 한 사람에게 스탬프를 막 찍어줄 수는 없다. 반드시 주문이 완료 된 후에, 주문한 잔 수 만큼 스탬프를 찍어주어야 한다. 이렇게 사전 작업이 완료된 후에 처리해야 하는 작업의 경우에는 동기식 처리가 적절하다.
동기식 처리의 장단점 : 직관적이고 프로그램 작성이 쉽지만 과정이 완료되기 전까지 다른 작업을 할 수 없다.
비동기식 처리의 장단점 : 구현이 좀 더 어렵지만 동시에 다른 작업이 가능하므로 효율적이다. 작업에 순서가 없고 히스토리가 남지 않는다. 연속으로 요청이 전달 될 경우 부하가 걸릴 수 있다.
1. JAVA에서 비동기 방식을 사용해보자
1 |
|
1 |
|
우선 동기을 살펴보자. 위 예제는 실제로 비동기 방식을 많이 사용하는 카톡, 문자 발송을 log처리로 대체한 예제이다. 발송 처리에 드는 작업시간은 Thread sleep으로 대체하였고, api가 호출되면 전체 데이터를 조회하여 그만큼을 로그 발송 처리하는 프로그램이다. api를 호출해보면 전체 처리에 다음과 같은 시간이 소요된다.
1 |
|
이번에는 비동기 방식으로 처리했을 때의 코드이다. CompletableFuture
라이브러리의 runAsync
는 리턴값이 없을 때 사용할 수 있는 비동기 처리 방식이다. 아래의 실행 시간을 확인해보면 훨씬 단축된 것을 확인 할 수 있다.
1 |
|
1 |
|
2. POSTMAN으로 응답 속도 비교
포스트맨으로 동기/비동기 방식으로 API를 호출해 보았을 때의 차이를 보면, (25.25s -> 38.85ms)상당한 속도 차이가 나는 것을 확인 할 수 있다.