- 제어권: 제어권은 자신(함수)의 코드를 실행할 권리 같은 것이다. 제어권을 가진 함수는 자신의 코드를 끝까지 실행한 후, 자신을 호출한 함수에게 돌려준다.
- 결과값을 기다린다는 것: A 함수에서 B 함수를 호출했을 때, A 함수가 B 함수의 결과값을 기다리느냐의 여부를 의미한다.
다른 함수를 호출할 때, 제어권도 함께 넘겨주고 작업이 끝난 후 돌려 받는 것이다.
부모함수가 A를 실행시킬 때 제어권을 아예 넘겨주게 되어서, 본인은 다른 일을 하지 못하고 A의 작업이 끝날때까지 마냥 기다리는 것이다. 그러다 A의 작업이 끝나면 제어권을 돌려받고 다음함수인 B를 실행시킨다.
제어권을 넘겨주긴하지만 바로 돌려받는다. A작업이 끝나도 바로 제어권을 돌려받고 부모 함수는 B작업을 시작한다.
일상 생활에 비유를 해보자면, 내가 요청하고 상대방이 요청받는 경우라고 가정했을 때, 블로킹은 요청해놓고 아무것도안하고 그것만 주구장창 기다리는 것이고, 논블로킹은 요청해놓고 다른 할 일을 하고있는 방식이라 할 수 있다.
블로킹/논블로킹을 구분짓는 기준은 '요청받은 함수가 제어권을 언제 돌려주는지' 였다. 이번에 이야기할 동기/비동기는 작업을 실행하는 호출되는 함수의 작업 완료 여부를 신경쓰는지의 여부에 따라 달라진다.
함수 A가 함수 B를 호출한 뒤, 함수 B의 리턴값을 계속 확인하면서 신경쓰는 것이 동기이다.
또 다른 관점에서는 제어권과 결과값을 동시에 반환하는 것을 말하기도 한다.
함수 A가 함수 B를 호출할 때 콜백 함수를 함께 전달해서, 함수 B의 작업이 완료되면 함께 보낸 콜백 함수를 실행한다.
함수 A는 함수 B를 호출한 후로 함수 B의 작업 완료 여부에는 신경쓰지 않는다.
동기는 요청작업이 끝났는지 내가 계속 물어보고 그 시간에 맞춰서 다른 작업을 수행하는 방식이고, 비동기는 작업을 해달라는 요청만 해놓고 더이상 신경쓰지 않고 있다가, 상대방이 끝나면 끝났다고 말해주는 방식이라 할 수 있다.
=> 프로그램적으로 제어가능하면 동기/비동기(동기적 프로그래밍/비동기적프로그래밍), 제어권으로 제어하는거면 블로킹 논블로킹.

다른 작업이 실행되는 동안 자신의 작업을 처리하지 않고, 다른 작업의 완료 여부를 바로 받아 순차적으로 처리하는 방식이다. 다른 작업의 결과가 자신의 작업에 영향을 주는 경우에 활용할 수 있다.
대표적으로 C나 JAVA의 코드 실행 후 커맨드에서 입력을 받는 경우가 이에 해당된다. 사용자로부터 입력을 받아야 그 입력값을 가지고 내부 처리를 하여 결과값을 콘솔에 출력해주기 때문에 순차적인 작업이 요구된다. 내부적으로 본다면 실행 코드가 콘솔창을 띄우고 Please enter your name 텍스트를 치고 난 다음 사용자의 리턴값이 필요하기 때문에 제어권을 시스템에서 사용자로 넘겨 사용자가 값을 입력할때까지 기다리는 것이다.

Sync Non-Blocking 조합은 다른 작업이 진행되는 동안에도 자신의 작업을 처리하고 (Non Blocking), 중간 중간 작업 완료 여부를 확인하고 다른 작업의 결과를 바로 처리하여 작업을 순차대로 수행 하는 (Sync) 방식이다.
스레드(Thread) 객체를 만들어 요청 작업을 백그라운드에 돌게 하고 메인 메서드에서 while문을 통해 스레드가 모두 처리되었는지 끊임없이 확인하고, 처리가 완료되면 다음 메인 작업을 수행한다.

Async-blocking의 경우는 사실 잘 마주하기 쉽지 않다. A 함수는 B 함수의 리턴값에 신경쓰지 않고, 콜백함수를 보낸다(비동기). 그런데, B 함수의 작업에 관심없음에도 불구하고, A 함수는 B 함수에게 제어권을 넘긴다(블로킹).
따라서, A 함수는 자신과 관련 없는 B 함수의 작업이 끝날 때까지 기다려야 한다.
보통 Async-blocking은 개발자가 비동기 논블록킹으로 처리 하려다가 실수하는 경우에 발생하거나, 자기도 모르게 블로킹 작업을 실행하는 의도치 않은 경우에 사용된다. 그래서 이 방식을 안티 패턴(anti-pattern)이라고 보기도 한다.
다만 Async Blocking 이 실제로 적용된 실무 사례가 있긴 하다. Node.js + MySQL의 조합이 대표적인데, Node.js에서 비동기 방식으로 데이터베이스에 접근하기 때문에 Async 이지만, MySQL 데이터베이스에 접근하기 위한 MySQL 드라이버가 블로킹 방식으로 작동되기 때문이다.
하지만 이러한 조합은 오히려 개발자에게 혼동만 일으키기 때문에 그래서 실무에서는 Node.js 서버 프로그래밍할때 아예 async/await로 동기 처리를 하는 편이다.
Async Non Blocking 조합은 다른 작업이 진행되는 동안에도 자신의 작업을 처리하고 (Non Blocking), 다른 작업의 결과를 바로 처리하지 않아 작업 순서가 지켜지지 않는 (Async) 방식이다. 다른 작업의 결과가 자신의 작업에 영향을 주지 않은 경우에 활용할 수 있다.
웹 브라우저는 웹 사이트에서 파일을 다운로드할 때, 파일의 전송이 완료될 때까지 다른 작업을 하지 않고 기다리는 것이 아니라, 다른 탭이나 창을 열거나 웹 서핑을 할 수 있다. 이는 웹 브라우저가 파일 다운로드를 비동기적으로 처리하고, 콜백 함수를 통해 다운로드가 완료되면 알려주는 방식으로 구현되어 있기 때문이다
블로킹은 다른 함수를 호출할 때 제어권을 넘겨주고 작업이 끝난 후 돌려받는 것이다. 요청자는 제어권을 돌려받을 때까지 다른 작업을 하지 않고 기다린다. 요청받은 함수는 작업이 끝나고 제어권과 결과값을 돌려받는다. 논블로킹은 다른 함수를 호출해도 제어권을 넘겨주지 않는다. 따라서 다른 함수를 실행해도 자신의 코드를 계속 실행한다.
sync는 함수 a가 함수b를 실행시켰을때 b의 결과값이 나올때까지 계속 확인하여 작업 완료 시간을 맞추는 것이다. async는 함수 a가 b를 호출할 때 콜백함수를 같이 전달해서 b작업이 끝나면 알아서 콜백함수를 실행하고, a는 b의 작업 완료 여부를 신경쓰지 않는다.
블로킹/논블로킹은 호출한 함수가 다른 작업이 끝날때까지 멈추느냐 차이이고, sync/async 호출된 작업의 완료를 누가 처리하느냐의 차이이다.
이것을 조합하면 4가지의 조합이 나온다. 먼저 sync-blocking은 가장 일반적인 형태로 작업이 끝날때까지 기다리며 결과값을 받아 직접 처리한다. 다른 함수의 결과값이 자신의 작업에 영향을 주는 경우에 사용한다. sync-non-blocking은 제어권은 있어 다른 작업이 실행되는 도중 자신의 작업을 처리하지만 중간중간 다른 작업의 완료여부를 확인하고 결과값을 받아 처리한다. (스레드 완료여부 확인) async-blocking은 A 함수는 B 함수의 리턴값에 신경쓰지 않고, 콜백함수를 보낸다(비동기). 그런데, B 함수의 작업에 관심없음에도 불구하고, A 함수는 B 함수에게 제어권을 넘긴다(블로킹). (sync-blocking과 차이가 없다.) async-non-blocking은 다른 작업을 처리하면서도 자신의 작업을 멈추지 않고, 다른 작업의 결과값을 바로 처리하지 않아 작업 순서가 보장되지 않는 방법이다. 다른 작업의 결과가 자신의 작업에 영향을 주지 않은 경우에 활용할 수 있다. (브라우저의 파일 다운로드)