Sync vs Async 와 Blocking vs Non-Blocking

김강욱·2022년 9월 22일

1. Sync vs Async

  먼저 SynchronousAsynchronous의 어원을 살펴봅시다. Syntogether을 의미하고 chronotime을 의미합니다. 즉 Synchronous의 의미는 함께 시간을 맞춘다는 뜻입니다. A는 접두사로 부정을 의미하기 때문에 Asynchronous는 시간을 함께 맞추지 않다는 뜻이 됩니다.

  Synchronous와 Asynchronous를 구분할 때는 무엇과 무엇이, 어떤 시간을 맞춘다? 안맞춘다? 이 두 가지를 반드시 언급해야합니다. 무슨 말인지 밑에서 좀 더 자세히 살펴보겠습니다.

1.1 Synchronous (동기)

  동기는 두 가지 이상의 대상이 서로 시간을 맞춰 행동하는 것으로 볼 수 있습니다. 예를 들어 메서드 호출에서 호출한 함수가 호출된 함수가 결과값을 반환할 때까지 기다리거나, 지속적으로 호출된 함수에게 진행상황을 요청하는 경우가 있습니다. A와 B라는 대상을 동기적으로 처리할 수 있는 방법에 대해 살펴보겠습니다.

 
A와 B가 동시에 시작하거나 동시에 종료하거나 동시에 같이 진행을 하면 동기라고 할 수 있습니다. 이러한 개념은 자바의 CyclicBarrier에서 볼 수 있습니다. CyclicBarrier는 여러 개의 쓰레드가 존재할 시 특정 지점에서 N개의 쓰레드가 도착할 때까지 대기하다 N개의 쓰레드가 도착한 이후 동시에 진행하는 걸 말합니다. 또한 메서드 호출에서도 볼 수 있습니다. 메서드 리턴시간(A)와 결과값 반환시간(B)가 일치하면 동기라 할 수 있습니다.

  위 그림과 같이 A가 끝나는 시간과 B가 시작하는 시간이 일치하는 것도 동기라 할 수 있습니다. 예를 들어 synchronized 블럭이나 BlockingQueue와 같이 순차적으로 어떠한 작업을 진행시킬 때 이러한 개념의 동기가 진행됩니다.

1.2 Asynchronous (비동기)

  비동기는 동기와 반대로 여러 개의 대상이 서로 시간을 맞춰 행동하지 않는 것입니다. 예를 들어 호출한 함수가 호출된 함수의 작업과 상관없이 자신의 작업을 진행하는 개념도 비동기로 볼 수 있습니다.

2. Blocking vs Non-Blocking

  농구에서 블록킹은 누군가가 슛팅하는 것을 막는 것을 의미합니다. 이와 같이 블록킹은 '막다', '멈추게하다'의 의미로 누군가의 작업을 진행하지 못하게 하는 뜻입니다. 자세한 내용은 아래에서 설명하도록 하겠습니다.

  동기/비동기와 블록킹/논블록킹은 서로 다른 관점의 개념입니다. 내가 직접 제어하지 못하는 제 3의 존재를 상대하는 방법에 대해 얘기할 때 블록킹/논블록킹의 개념을 꺼낼 수 있습니다.
예를 들어 어떤 메서드를 호출해서 데이터를 가져오고자 할 때 그 데이터의 원천 소스 자체가 내가 통제하지 못하는 외부의 어떤 제 3의 존재로부터 Input을 받아야 한다거나(IO 관점) 나말고 다른 쓰레드가 존재해서 어떤 작업을 하다가 어느 시점에 그 쓰레드로부터 결과를 확인받거나 그 쓰레드가 종료하는 것을 내가 확인하고 넘어가야할 때(멀티쓰레드 동기화 관점) 블록킹/논블록킹을 얘기할 수 있습니다.

2.1 Blocking

  블록킹은 직접 제어할 수 없는 대상의 작업이 끝날 때까지 제어권을 넘겨주지 않는 것입니다. 예를 들어 호출하는 메서드가 IO를 요청했을 때 IO를 처리하는 곳에 제어권이 있어 IO처리가 완료될 때까지 작업을 진행하지 못하고 기다리는 것을 의미합니다.

2.2 Non-Blocking

  논블록킹은 블록킹과 반대되는 개념으로 직접 제어할 수 없는 대상의 작업이 끝나는 것과 상관없이 작업을 진행하는 것을 의미합니다. 예를 들어 호출하는 메서드가 IO를 요청했을 때 IO를 처리하는 곳에서 바로 제어권을 넘겨주어 IO처리 완료 여부에 상관없이 자신의 작업을 할 수 있습니다.

3. Sync/Async,Blocking /Non-Blocking 예제

  동기/비동기와 블록킹/논블록킹은 다른 관점에서 독립적으로 바라봐야 합니다. 아래의 코드를 보며 동기/비동기, 블록킹/논블록킹을 분석해봅시다.

ExcutorService es = Executors.newCachedThreadPool();

String res = es.submit(()->"Hello Async").get();
profile
TO BE DEVELOPER

0개의 댓글