# 동기와 비동기 & 블로킹과 논블로킹

## 동기 & 비동기

`함수를 호출한 주체(caller)가 해당 함수의 작업 완료 여부를 확인하는지`에 따라 동기와 비동기로 나뉜다.

### `동기 작업`

함수를 호출한 주체(caller)가 해당 함수의 작업이 완료되었는지 확인하는 작업이다.

* **확인을 하는 이유 → 작업 순서를 맞추기 위함**
  1. 작업의 시작 시간과 종료 시간을 맞추기 위해서 (ex : 프로그램 설치 작업과 설치경과를 Progress Bar로 표시하는 작업)
  2. 작업의 시작 시간을 맞추기 위해서 (ex : 동영상 진행 Progress Bar와 회색 로딩 Progress Bar를 표시하는 작업)
  3. 하나의 작업이 끝나는 동시에 다른 작업을 시작하기 위해서 (ex : zip 파일을 풀고 프로그램을 설치하는 작업)

### `비동기 작업`

함수를 호출한 주체(caller)가 해당 함수의 작업이 완료되었는지 확인하지 않는 작업이다.

* 각각의 작업들이 별도의 시작 시간, 종료 시간을 가진다. (ex : html 파일을 화면에 그리는 작업과 img 태크에 이미지를 로드하는 작업)
* 대신 해당 함수의 작업 결과를 callback 함수로 받을 수 있다.

## 블로킹 & 논블로킹

`함수를 호출한 주체가 함수에게 제어권을 넘겨주는지` 에 따라 블로킹과 논블로킹으로 나뉜다.

### `블로킹`

함수를 호출한 주체(caller)가 제어권을 함수에게 넘겨준다.

* 제어권을 넘기기 때문에 전체적인 작업흐름이 막힌다 → 함수의 작업 결과가 완료될 때까지 다른 작업을 수행할 수 없다. (ex : Java에서 JDBC를 사용하여 DB에 쿼리를 날리고 결과를 받아오는 작업)

### `논블로킹`

함수를 호출한 주체가 제어권을 함수에게 넘겨주었다가 해당 함수가 바로 돌려준다.

* 제어권이 넘어가지 않기 때문에 전체적인 작업 흐름이 막히지 않는다. → 해당 함수의 작업 결과를 받을 때까지 대기하지 않고 다른 작업을 수행한다. (ex : thread를 실행하는 함수)

## 비교

| 비동기                                            | 논블로킹                                  |
| ---------------------------------------------- | ------------------------------------- |
| 작업 처리 순서를 맞추지 않기 때문에 호출한 함수의 작업 완료 여부를 확인하지 않음 | 호출한 함수에 제어권을 넘기지 않기 때문에 작업 흐름이 막히지 않음 |

| 동기                                           | 블로킹                            |
| -------------------------------------------- | ------------------------------ |
| 작업을 처리할 때 순서를 맞추기 때문에 호출한 함수의 작업 완료 여부를 확인 함 | 호출한 함수에 제어권을 넘기기 때문에 작업 흐름이 막힘 |

## 조합

![Untitled](https://826718011-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxzBwrJtOrGh4cRsnXzQX%2Fuploads%2Fgit-blob-4969b9f4acb62f90375cb668b1352558c74b8978%2FUntitled.png?alt=media)

* `동기` : 기능 A 개발이 선행되어야만 기능 B를 개발할 수 있다. → 기능 A의 작업 완료 여부를 확인하고, 완료되었으면 기능 B를 개발한다
* `비동기` : 기능 A와 B의 개발 순서가 따로 없다 → 기능 A의 작업 완료 여부를 확인하지 않고도 기능 B를 개발할 수 있다. 그리고 callback 함수를 통해 기능 A의 결과를 받을 수 있다.
* `블로킹` : 기능 A를 개발하는 동안 제어권이 넘어간다 → 작업 흐름이 blocked되어 다른 기능을 개발할 수 없다
* `논블로킹` : 기능 A를 개발하는 동안 제어권이 넘어가지 않는다. → 다른 작업을 할 수 있다.

### `동기 + 블로킹`

흔하게 접하는 동기 작업이다.

* 기능 A를 개발하는 동안 다른 작업을 하지 못하고, 기능 A의 완료 여부를 확인한다.

### `동기 + 논블로킹`

작업의 모든 실행과 흐름이 순차적이기 때문에 개발자가 프로그램을 제어하기 쉽다. (가장 많이 쓰이는 조합)

* 기능 A를 개발하는 동안 다른 작업(C)을 진행할 수 있다. 다만 개발 순서(A→B)가 정해져 있기 때문에 다른 작업을 진행하면서 기능 A의 완료여부를 지속적으로 확인한다.(polling)

### `비동기 + 블로킹`

작업의 흐름을 비동기로 설계했지만 블로킹 때문에 동기 + 블로킹 과 같은 흐름을 갖는다.

* 기능 A를 개발하는 동안 다른 작업을 진행하지 못한다. 개발 순서가 따로 없기 때문에 기능 A의 완료여부를 확인하지 않고 callback함수를 통해 결과를 받는다.

1. 의도치 않게 비동기 + 블로킹으로 동작하는 경우가 있다.
2. 직관적인 코드 흐름을 유지하면서, 작업을 병렬적으로 처리하기 위해 사용하기도 한다.
   * 동기 + 블로킹 ⇒ IO 작업을 수행할 때 직관적이나, 여러 IO 작업을 병렬적으로 수행할 수 없음
   * 논블로킹 ⇒ IO 작업을 컨트롤하기 어렵다

### `비동기 + 논블로킹`

성능과 자원 효율면에서 가장 우수하여 많이 쓰이는 조합이다.

* 기능 A를 개발하는 동안 다른 작업을 진행할 수 있다. 또한 개발 순서가 따로 없기 때문에 기능 A의 완료 여부를 확인하지 않고 callback 함수를 통해 결과를 받는다.
