먼저 Synchronous와 Asynchronous의 어원을 살펴봅시다. Syn은 together을 의미하고 chrono는 time을 의미합니다. 즉 Synchronous의 의미는 함께 시간을 맞춘다는 뜻입니다. A는 접두사로 부정을 의미하기 때문에 Asynchronous는 시간을 함께 맞추지 않다는 뜻이 됩니다.
Synchronous와 Asynchronous를 구분할 때는 무엇과 무엇이, 어떤 시간을 맞춘다? 안맞춘다? 이 두 가지를 반드시 언급해야합니다. 무슨 말인지 밑에서 좀 더 자세히 살펴보겠습니다.
동기는 두 가지 이상의 대상이 서로 시간을 맞춰 행동하는 것으로 볼 수 있습니다. 예를 들어 메서드 호출에서 호출한 함수가 호출된 함수가 결과값을 반환할 때까지 기다리거나, 지속적으로 호출된 함수에게 진행상황을 요청하는 경우가 있습니다. A와 B라는 대상을 동기적으로 처리할 수 있는 방법에 대해 살펴보겠습니다.
A와 B가 동시에 시작하거나 동시에 종료하거나 동시에 같이 진행을 하면 동기라고 할 수 있습니다. 이러한 개념은 자바의 CyclicBarrier에서 볼 수 있습니다. CyclicBarrier는 여러 개의 쓰레드가 존재할 시 특정 지점에서 N개의 쓰레드가 도착할 때까지 대기하다 N개의 쓰레드가 도착한 이후 동시에 진행하는 걸 말합니다. 또한 메서드 호출에서도 볼 수 있습니다. 메서드 리턴시간(A)와 결과값 반환시간(B)가 일치하면 동기라 할 수 있습니다.
위 그림과 같이 A가 끝나는 시간과 B가 시작하는 시간이 일치하는 것도 동기라 할 수 있습니다. 예를 들어 synchronized 블럭이나 BlockingQueue와 같이 순차적으로 어떠한 작업을 진행시킬 때 이러한 개념의 동기가 진행됩니다.
비동기는 동기와 반대로 여러 개의 대상이 서로 시간을 맞춰 행동하지 않는 것입니다. 예를 들어 호출한 함수가 호출된 함수의 작업과 상관없이 자신의 작업을 진행하는 개념도 비동기로 볼 수 있습니다.
농구에서 블록킹은 누군가가 슛팅하는 것을 막는 것을 의미합니다. 이와 같이 블록킹은 '막다', '멈추게하다'의 의미로 누군가의 작업을 진행하지 못하게 하는 뜻입니다. 자세한 내용은 아래에서 설명하도록 하겠습니다.
동기/비동기와 블록킹/논블록킹은 서로 다른 관점의 개념입니다. 내가 직접 제어하지 못하는 제 3의 존재를 상대하는 방법에 대해 얘기할 때 블록킹/논블록킹의 개념을 꺼낼 수 있습니다.
예를 들어 어떤 메서드를 호출해서 데이터를 가져오고자 할 때 그 데이터의 원천 소스 자체가 내가 통제하지 못하는 외부의 어떤 제 3의 존재로부터 Input을 받아야 한다거나(IO 관점) 나말고 다른 쓰레드가 존재해서 어떤 작업을 하다가 어느 시점에 그 쓰레드로부터 결과를 확인받거나 그 쓰레드가 종료하는 것을 내가 확인하고 넘어가야할 때(멀티쓰레드 동기화 관점) 블록킹/논블록킹을 얘기할 수 있습니다.
블록킹은 직접 제어할 수 없는 대상의 작업이 끝날 때까지 제어권을 넘겨주지 않는 것입니다. 예를 들어 호출하는 메서드가 IO를 요청했을 때 IO를 처리하는 곳에 제어권이 있어 IO처리가 완료될 때까지 작업을 진행하지 못하고 기다리는 것을 의미합니다.
논블록킹은 블록킹과 반대되는 개념으로 직접 제어할 수 없는 대상의 작업이 끝나는 것과 상관없이 작업을 진행하는 것을 의미합니다. 예를 들어 호출하는 메서드가 IO를 요청했을 때 IO를 처리하는 곳에서 바로 제어권을 넘겨주어 IO처리 완료 여부에 상관없이 자신의 작업을 할 수 있습니다.
동기/비동기와 블록킹/논블록킹은 다른 관점에서 독립적으로 바라봐야 합니다. 아래의 코드를 보며 동기/비동기, 블록킹/논블록킹을 분석해봅시다.
ExcutorService es = Executors.newCachedThreadPool();
String res = es.submit(()->"Hello Async").get();
es.submit(() -> "Hello Async"): 비동기
- submit() 메서드의 리턴 시간과 Callable의 실행 결과를 받는 시간이 일치하지 않습니다.
- 블록킹/논블록킹을 고려할 대상이 아닙니다.
get(): 동기/블록킹
- get() 메서드의 리턴 시간과 결과를 가져오는 시간이 일치합니다.(동기)
- 다른 쓰레드의 작업이 완료될 때까지 대기합니다.(블록킹)
참고자료
[10분 테코톡] 우의 Block vs Non-Block & Sync vs Async 우아한테크코스 테코톡[Youtube]
스프링캠프 2017 Async & Spring 이일민[Youtube]