|
| 1 | +# Sync, Async, Blocking, Non-blocking |
| 2 | + |
| 3 | +동기와 비동기, 블록킹과 논블록킹의 차이에 대해서 설명할 수 있는가? |
| 4 | + |
| 5 | +## 기본 개념 |
| 6 | + |
| 7 | +잘 이해가 가지 않지만, 한 가지 약속을 하고 가야할 것이 있다. |
| 8 | + |
| 9 | +- Sync, Async : 결과값의 반환에 관한 것 |
| 10 | +- Blocking, Non-blocking : 제어권의 반환과 관련된 것 |
| 11 | + |
| 12 | +그러니까 동기 비동기는 결과값, 블록킹 논 블록킹은 제어권과 관련된 얘기라고 약속을 하고 가자. |
| 13 | + |
| 14 | +## Sync |
| 15 | + |
| 16 | +- `Sync(동기)` : A 함수가 B 함수를 호출할 때, B 함수의 결과를 A 함수가 처리하는 것. |
| 17 | +- 그러니까 B의 결과값을 A가 직접 처리하기 위해, B의 종료를 계속 확인하게 되는 것이다. |
| 18 | +- A,B의 시작 시간 또는 종료 시간이 일치하는 것도 동기라고 한다. (자바에서 `CyclicBarrier`, `Synchronized`, `BlockingQueue`) |
| 19 | + |
| 20 | +## Async |
| 21 | + |
| 22 | +- `Async(비동기)` : A 함수가 B 함수를 호출할 때, B 함수의 결과를 B 함수가 처리하는 것. |
| 23 | + |
| 24 | +- 결과값의 관점에서 보면, A 함수는 B 함수의 결과값을 처리할 필요가 없으므로 B의 종료를 확인 하지 않는다. 나중에 B 함수가 A 함수에게 `Callback`으로 종료를 알리며 리턴 값을 주는 방식이다. |
| 25 | + |
| 26 | +그러니까 동기는 결과값이 필요하므로 작업의 주체가 A한테 있는 것이고, 비동기는 필요 없으므로 주체가 B한테 있다고 생각하면 될 것이다. |
| 27 | + |
| 28 | +## Blocking |
| 29 | + |
| 30 | +- A 함수가 B 함수를 호출할 때 B 함수에게 제어권을 넘겨주고, B 함수는 작업이 종료되기 전까지 A에게 제어권을 넘겨 주지 않는다. |
| 31 | +- 따라서 작업의 주체가 누구냐에 상관 없이 제어권을 돌려받을 때까지 A 함수는 멈추게 된다. |
| 32 | + |
| 33 | +## Non-blocking |
| 34 | + |
| 35 | +- A 함수가 B 함수를 호출할 때, 제어권을 넘겨주었다가 바로 돌려받는다고 생각하면 된다. 제어권을 A가 갖고 있으므로 B 함수와 관계 없이 자신의 작업을 계속 진행할 수 있다. |
| 36 | + |
| 37 | +이 4가지 개념은 같이 쓰이므로, 예를 보면서 확인해보자. |
| 38 | + |
| 39 | +## Sync + Blocking |
| 40 | + |
| 41 | +<p align="center"> |
| 42 | + <img src="./img/syncblock.png" width="400px"> |
| 43 | + <br /> |
| 44 | + Sync Blocking I/O |
| 45 | +</p> |
| 46 | + |
| 47 | +Blocking이므로 당연히 다른 작업을 진행할 수 없고, Sync이므로 결과를 가져오는 시간과 리턴하는 시간이 일치한다. |
| 48 | + |
| 49 | +## Async + Non-blocking |
| 50 | + |
| 51 | +<p align="center"> |
| 52 | + <img src="./img/asyncnonblock.png" width="400px"> |
| 53 | + <br /> |
| 54 | + Async + Non-blocking |
| 55 | +</p> |
| 56 | + |
| 57 | +Non-blocking이므로 당연히 다른 작업을 진행할 수 있고, Async이므로 작업의 종료 여부를 callback을 이용하여 받는다. |
| 58 | + |
| 59 | +성능적으로 최대의 효율을 뽑을 수 있는 모델이다. |
| 60 | + |
| 61 | +조금 더 보기 쉽게 두가지를 그려보면, |
| 62 | + |
| 63 | +<p align="center"> |
| 64 | + <img src="./img/syncblock2.png" width="400px"> |
| 65 | + <br /> |
| 66 | + Sync-Blocking, Async-NonBlocking |
| 67 | +</p> |
| 68 | + |
| 69 | +이렇게 될 수 있겠다. |
| 70 | +여기까지는 직관적으로 이해가 가능한데, 나머지 두 가지 모델이 굉장히 헷갈린다. |
| 71 | + |
| 72 | +## Sync + Non-blocking |
| 73 | + |
| 74 | +<p align="center"> |
| 75 | + <img src="./img/syncnonblock.png" width="400px"> |
| 76 | + <br /> |
| 77 | + Sync Non-Blocking I/O |
| 78 | +</p> |
| 79 | + |
| 80 | +<p align="center"> |
| 81 | + <img src="./img/syncnonblock2.png" width="400px"> |
| 82 | + <br /> |
| 83 | + Sync NonBlocking Model |
| 84 | +</p> |
| 85 | + |
| 86 | +위 두 그림을 살펴보자. |
| 87 | + |
| 88 | +우리가 앞서 얘기했던 것처럼, Sync는 함수의 주체, 결과값에 신경을 쓰고, NonBlocking은 제어권에 대해 신경을 쓴다고 하였다. |
| 89 | + |
| 90 | +그리하여, NonBlocking이므로 제어권을 곧바로 가져와 다른 작업을 수행할 수 있다. 그러나, Sync이므로 A 함수가 B 함수의 주체이므로, 주기적으로든 어떻게든 B 함수의 종료를 계속 확인해 주어야 한다. |
| 91 | + |
| 92 | +중간 중간 리턴 받는 것도, **아직 종료가 되어 있지 않다는 결과값**을 받은 것 이라고 생각하면 이해하기 쉬울 것 같다. |
| 93 | + |
| 94 | +## Async + Blocking |
| 95 | + |
| 96 | +이 모델은 직관적으로 생각해봐도 굉장히 비효율적이라 사용하지 않는다. 다만, 의도치 않게 이러한 모델로 동작하는 경우가 있는데, 바로 Node.js + MySQL이 대표적인 예라고 한다. |
| 97 | + |
| 98 | +Node.js는 Async로 동작하게 되는데, DB 작업 호출 시에는 MySQL에서 제공하는 드라이버를 이용하게 된다. 이 때, MySQL 드라이버가 Blocking 방식이라, Async-Blocking 방식을 사용하게 된다. |
| 99 | + |
| 100 | +Java의 JDBC 또한 마찬가지라고 한다. 하지만 Node.js는 싱글 쓰레드 루프 기반이고, Java는 멀티 쓰레드 루프 기반이므로 Java의 Servlet 컨테이너보다 심각하게 보일 뿐이지만 JDBC + MySQL도 이러한 문제점이 있다는 것을 알아두자. |
| 101 | + |
| 102 | +Java의 Blocking 해결법은 R2DBC를 사용하는 것이 있는데, Spring MVC 와 조합보다는 Spring WebFlux + R2DBC를 많이 사용하는 것 같다. 아마 Spirng MVC + JDBC 조합을 대체할 수 없는 것 같다. |
| 103 | + |
| 104 | +# Reference |
| 105 | + |
| 106 | +https://velog.io/@codemcd/Sync-VS-Async-Blocking-VS-Non-Blocking-sak6d01fhx |
| 107 | + |
| 108 | +https://wbluke.tistory.com/49 |
| 109 | + |
| 110 | +https://jh-7.tistory.com/25 |
| 111 | + |
| 112 | +[우테코 테코톡](https://www.youtube.com/watch?v=oEIoqGd-Sns) |
0 commit comments