오봉이와 함께하는 개발 블로그

Sync & Async / Blocking & Non-Blocking 본문

자바

Sync & Async / Blocking & Non-Blocking

오봉봉이 2023. 11. 23. 23:58
728x90

개요

문득 Sync & Async / Block & Non-Block에 대해 명확하게 알고 있는지, 남에게 잘 설명할 수 있는지를 생각했는데 자신 없다고 느껴 글로 정리하려 한다.
자칫 같은 개념이라 생각할 수 있지만 둘은 다른 개념이며 당연히 동작 또한 다르다. 나와 같은 질문 혹은 고민을 가진 사람이 이 글을 보고 명쾌하게 답을 얻어갔으면 한다.

Blocking & Non-Blocking

먼저 Blocking과 Non-Blocking에 대해 설명하면 이 개념의 관심사는 제어권에 있다.

functionA에서 functionB를 호출할 때 Blocking은 functionB를 수행하는 동안 더이상 functionA가 진행되지 않고 대기하는 상황이다.
즉 함수 제어권이 functionB로 넘어가 functionA가 Blocking 상황에 있는 것이다.
그렇다면 당연히 Non-Blocking은 functionA에서 funtcionB를 호출하면 functionB는 따로 동작하고, functionB를 호출한 다음 line을 이어서 수행하여 functionA에서 functionB를 호출했을 뿐 제어권은 여전히 functionA에 남아 동작하는 것이 Non-Blocking이다.

functionA(){
    line30  .....
    line45  functionB();
    line46  .....
}

functionB() {
    .....
}

위와 같은 코드가 있다고 했을 때를 가정하여 생각해보자.

  • Blocking
    1. line 30 ~ 44 수행하며 functionA()가 제어권을 가짐
    2. line 45에서 functionB() 수행
    3. functionB()로 제어권이 넘어가서 functionB() 수행
    4. functionB()의 모든 코드가 수행되면 functionA()로 제어권이 넘어가 functionA()의 line46 수행
  • Non-Blocking
    1. line 30 ~ 44 수행하며 functionA()가 제어권을 가짐
    2. line 45에서 functionB() 수행
    3. functionB()로 제어권이 넘어가서 functionB() 수행과 거의 동시에 다시 제어권을 functionA()로 반환
    4. functionB()가 수행되며 동시에 functionA()의 line46 이후 동작 수행

Sync & Async

Blocking과 Non-Blocking의 관심사는 제어권에 있다고 했는데 Sync와 Async의 관심사는 작업 순서완료 여부다.
Sync와 Async는 작업 순서와 완료 여부를 관리하기 위해 사용하는 키워드다.

functionA에서 functionB를 호출할 때 functionA가 functionB의 종료를 기다리며 functionB에게 지속적으로 결과를 요청, 결과값을 받고 다음 순서의 작업을 수행하면 Sync(동기) functionB의 종료를 기다리지 않고 functionA의 다음 작업을 수행하며 functionB가 작업 완료를 functionA에 알려주는 경우를 Async(비동기)라고 한다. 이때 functionB의 함수 수행 결과는 callback 함수로 반환되어 간접적으로 받게 된다.

functionA(){
    line30  .....
    line45  someData = functionB();
    line46  .....
    line99  someData.getData();
}

functionB() {
    .....
    return someData;
}

위와 같은 코드가 있고, 편의를 위해 Non-Blocking인 상황으로 가정하여 생각해보자.

  • Sync
    1. line 30 ~ 44 수행하며 functionA() 수행
    2. line 45에서 functionB() 호출
    3. functionB()로 제어권이 넘어가서 functionB() 수행과 거의 동시에 다시 제어권을 functionA()로 반환
    4. functionA()가 line 46 이후부터 지속적으로 functionB()에게 결과를 요청
    5. functionA() 수행 중 line 99를 만났을 때 functionB()의 수행이 끝나지 않았다면 대기
    6. functionB()의 수행이 끝나 someData를 사용 가능하면 line99 수행
  • Async
    1. line 30 ~ 44 수행하며 functionA() 수행
    2. line 45에서 functionB() 수행
    3. functionB()로 제어권이 넘어가서 functionB() 수행과 거의 동시에 다시 제어권을 functionA()로 반환
    4. functionB()가 수행되며 동시에 functionA()의 line46 이후 동작 수행
    5. functionA()는 functionB()의 결과에 관심 갖지 않고 functionA()의 나머지 동작 수행
    6. functionB()의 수행이 완료되면 functionB()가 functionA()에게 결과 전달
    7. functionA()에서 코드 수행

Non-Blocking/Async인 상황에서 조심해야 할 점은 데이터 정합성이다.
여러 곳에서 비동기로 한 데이터에 조작을 시도하면 해당 코드에서 데이터의 정합성이 맞지 않아 엉뚱한 결과를 도출할 수 있기 때문에 상태 관리를 잘해야 한다.

참고

마지막으로 유명한 표 하나를 첨부한다.

728x90
Comments