도메인 주도 개발이라는 책을 읽으면서 이벤트라는 개념을 알게 되었고, 이벤트는 비동기적인 방식으로 동작한다라는 것을 알게되었다.
동기와 비동기의 차이에 대해서 이해 해보고, 동기 비동기를 언급하면서 Blocking, Non-blocking 이라는 용어도 등장하는데 이러한 용어들의 개념과 차이를 알아보자.
📌 Sync(동기) vs Async(비동기)
단순히 생각하면 동기는 특정 작업이 끝날 때 까지 기다리고, 순차적으로 실행되는 방식이다.
반면에 비동기는 다른 작업이 끝나지 않아도 기다리지 않고 자신의 동작을 수행하는 방식입니다.
하지만, 이렇게 단순히 생각하면 Blocking, Non-blocking 관점을 생각했을 때 해석이 먼가 어렵게 되는 것 같다.
그래서 나는 다음과 같이 이해하려고 한다.
동기방식은 A가 B에게 "야, 요청 결과 내놔!"
비동기 방식은 A가 B에게 "야, 이 작업 맡길테니까 너 알아서 해!"
위처럼 생각하면서 Blocking과 Non-blocking을 대입해서 생각해보자.
📌 Blocking vs Non-blocking
Blocking방식은 더 이상 진행하지 않고 기다리는 상태이다.
Non-blocking방식은 막힘없이 진행한다 라고 생각해도 될 것 같다.
이러한 Blocking과 Non-blocking의 특징을 동기/비동기 관점에서 생각할 수 있다.
크게 스레드와 운영체제간의 입출력 I/O 방식의 4가지 예시로 많이 설명하는 듯 하다.
📌 Blocking / Synchronous(동기)
- 위에서 동기는 A가 B에게 "야, 요청 결과 내놔!" 라고 했다.
- 그래서 특정 작업을 요청하고 요청결과를 기다린다.
- 기다리는데 진짜로 Block돼서 결과값 줄 때까지 아무것도 안한다.
📌 Non-blocking / Synchronous(동기)
- 마찬가지로 동기는 A가 B에게 "야, 요청 결과 내놔!" 이다.
- 그럼 Non-blocking이니까 막힘없이 실행이 되어야 한다(머야 그럼 결과를 달라고 재촉하는게 동기라며?)
- 그래서 B는 A에게 요청하자마자 진짜로 결과를 그냥 바로 준다. 그런데 이 결과는 실제 I/O결과가 아닌 "아직 완료되지 않음"의 상태를 가지는 결과이다.(요게 포인트★)
- 그래서 A는 B한테 내놔! 라고해서 결과를 바로 받고, 막힘없이(Non-blocking)방식으로 진행한다.
- 단, A는 계속해서 코드를 실행함과 동시에 주기적으로 B에 요청이 모두 처리되었는지 물어보면서 확인한다. 확인해 봤는데 처리되었으면 그때 진짜 결과 데이터를 받는다.
- 주기적으로 요청이 처리되었는지를 계속해서 물어보기 때문에, 처리되자마자 곧바로 데이터를 받을 수 있으리란 보장이 없고, 성능상 좋지못하다는 특징이 있다.
📌 Non-blocking / Asynchronous(비동기)
- 비동기는 방식은 A가 B에게 "야, 이 작업 맡길테니까 너 알아서 해!" 라고 했었다.
- B에게 일을 위임했으니 A는 Non-blocking이니까 그냥 막힘없이 자신의 일을 수행한다.
- 그러다가, 위임한 요청이 완료되면 콜백과 함께 데이터를 전달받는다.
- 콜백에 따라서 결과값에 따른 후속작업을 처리할 수 있다.(javascript의 fetch함수를 생각해볼 수 있다.)
📌 Blocking / Asynchronous(비동기)
- 마찬가지로 비동기 방식은 A가 B에게 "야, 이 작업 맡길테니까 너 알아서 해!" 라고 했었다.
- 그러면 A는 B에게 작업을 위임했는데, 이제 머함?
- Blocking이니까 아무것도 안하고 있는다.
- 그러다가, B에게 알림이 오게되고, "먼가 데이터가 왔구나"라고 생각한 A는 B에게 "그럼 데이터 줘" 라고 하고 데이터를 받는다.
- ex) 서버의 소켓과같은 입/출력 I/O에 사용된다.
- ex) 여러개의 소켓이 열려있을 수 있고, 특정 데이터를 전송받았는지 알림을 기다리면서 대기한다.(제어권은 있지만 알림올때까지 대기함 -> 알림이 오면 데이터를 읽고 처리함)
- 결과적으로 알림이 올때까지 기다리는 방식이기 때문에 Blocking방식이라고 한다.
이렇게 Blocking방식과 Non-blocking 방식에서의 동기, 비동기를 알아보았는데, 많이 헷갈렸던 부분이어서 최대한 나만의 방식으로 이해하려고 했다.
실제 프로그래밍 개발을 할때에는 비동기 방식이라고 했을 때, 자신의 작업을 수행하다가 또다른 스레드 혹은 프로세스에게 멀티태스킹 작업을 위임하고 자신의 작업을 막힘없이 수행하는 방식이라는 의미로 쓰이는 것 같다.
이벤트라는 개념 또한 비동기 방식으로 다른 스레드(혹은 프로세스)에게 작업을 요청/위임하는 방식을 의미한다.
개념적으로 알아보았으니 자바 혹은 스프링(내가 사용할 수 있는 기술들)에서 비동기 방식의 프로그래밍 실습도 해봐야겠다.
'동시성 프로그래밍' 카테고리의 다른 글
모니터와 자바 동기화(synchronized) (0) | 2024.04.06 |
---|---|
[Java] 가상 스레드 (0) | 2024.01.11 |
[자바 멀티쓰레드] CPU와 캐시메모리에 따른 데이터 문제 (0) | 2023.09.07 |
[자바 멀티쓰레드] 동기화 기법 (0) | 2023.09.07 |
[자바 멀티쓰레드] 경쟁상태와 임계영역 (0) | 2023.09.07 |