티스토리 뷰
Programming
비동기(Asynchronous) vs. 동기(Synchronous), 블로킹(Blocking) vs. 논블로킹(Non-blocking)
ipxy 2025. 3. 18. 11:09728x90
비동기(Asynchronous) vs. 동기(Synchronous)
작업 간의 실행 순서를 결정하는 개념입니다.
- 동기(Synchronous): 요청을 보낸 후 응답이 올 때까지 기다리는 방식
- 작업이 순차적으로 실행됨
- 한 작업이 끝나야 다음 작업이 실행됨
- 예: 전화 통화 (상대방이 응답해야 대화 가능)
- 비동기(Asynchronous): 요청을 보낸 후 응답을 기다리지 않고 다음 작업을 실행하는 방식
- 응답이 언제 도착할지 몰라도 다른 작업을 계속 수행할 수 있음
- 예: 문자 메시지 (보내놓고 상대방이 언제 답장할지 몰라도 다른 일을 할 수 있음)
블로킹(Blocking) vs. 논블로킹(Non-blocking)
작업이 자원을 사용하는 동안 대기하는지 여부를 결정하는 개념입니다.
- 블로킹(Blocking): 요청한 작업이 완료될 때까지 현재 실행 중인 코드가 멈춤
- 함수 호출이 끝날 때까지 다른 작업을 수행할 수 없음
- 예: 파일을 읽을 때 읽기 작업이 끝날 때까지 프로그램이 멈춤
- 논블로킹(Non-blocking): 작업을 요청한 후 바로 반환되며, 다른 작업을 계속 수행할 수 있음
- 예: 파일을 읽을 때 즉시 제어권을 반환하고, 데이터가 준비되면 처리
개념 비교
동기(Synchronous) 비동기(Asynchronous) 블로킹(Blocking) 논블로킹(Non-blocking)
설명 | 요청 후 응답을 기다림 | 요청 후 응답을 기다리지 않음 | 요청한 작업이 완료될 때까지 멈춤 | 요청한 작업이 완료되지 않아도 바로 다음 코드 실행 |
예시 | 전화 통화 | 문자 메시지 | 파일 읽을 때 대기 | 파일 읽기 요청 후 다른 작업 수행 |
코드 실행 흐름 | 순차적으로 진행 | 다른 작업과 병행 가능 | 실행이 멈춤(대기) | 실행이 멈추지 않음 |
조합 예제
- 동기 + 블로킹: 요청을 보낸 후 작업이 끝날 때까지 기다림
- 예: 일반적인 함수 호출
- 동기 + 논블로킹: 요청을 보내고 바로 반환하지만, 응답을 받을 때까지 직접 확인(Polling)
- 예: while 루프를 이용한 상태 확인
- 비동기 + 블로킹: 요청을 보낸 후 응답을 기다리는 동안 다른 작업을 할 수 있지만, 특정 작업이 끝날 때까지 멈춤
- 예: Future.get() 호출
- 비동기 + 논블로킹: 요청을 보내고 다른 작업을 계속 수행하며, 응답이 준비되었을 때 콜백 함수로 처리
- 예: CompletableFuture.thenAccept()
자바 코드 예제
1. 동기 + 블로킹
public class SyncBlockingExample {
public static void main(String[] args) {
System.out.println("작업 시작");
try {
Thread.sleep(3000); // 3초 동안 블로킹
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("작업 완료");
}
}
실행 흐름:
- Thread.sleep(3000) 실행
- 3초 동안 프로그램이 멈춤 (블로킹)
- 이후 "작업 완료" 출력
2. 동기 + 논블로킹
public class SyncNonBlockingExample {
public static void main(String[] args) {
System.out.println("작업 시작");
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < 3000) {
// 3초 동안 대기, 하지만 블로킹 없이 반복문 진행
}
System.out.println("작업 완료");
}
}
실행 흐름:
- while 루프에서 계속 실행되지만, 멈추지 않고 반복
- CPU를 계속 사용하므로 비효율적 (Polling 방식)
3. 비동기 + 블로킹 (Future 사용)
import java.util.concurrent.*;
public class AsyncBlockingExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
System.out.println("작업 시작");
Future<String> future = executor.submit(() -> {
Thread.sleep(3000); // 3초 후 결과 반환
return "작업 완료";
});
try {
String result = future.get(); // 결과를 기다리는 동안 블로킹됨
System.out.println(result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
executor.shutdown();
}
}
실행 흐름:
- Future를 사용해 비동기 작업 실행
- future.get()을 호출하면 결과를 기다리면서 블로킹
4. 비동기 + 논블로킹 (CompletableFuture 사용)
import java.util.concurrent.*;
public class AsyncNonBlockingExample {
public static void main(String[] args) {
System.out.println("작업 시작");
CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000); // 3초 대기 후 결과 반환
} catch (InterruptedException e) {
e.printStackTrace();
}
return "작업 완료";
}).thenAccept(result -> System.out.println(result)); // 결과가 준비되면 실행
System.out.println("다른 작업 수행 중...");
try {
Thread.sleep(5000); // 메인 스레드 종료 방지
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
실행 흐름:
- supplyAsync()를 통해 별도 스레드에서 작업 실행
- thenAccept()를 사용해 결과가 준비되면 출력
- get()을 호출하지 않아서 블로킹되지 않음
- "다른 작업 수행 중..."을 먼저 출력한 후 3초 후에 "작업 완료"가 출력됨
정리
동기(Synchronous) 비동기(Asynchronous)
블로킹(Blocking) | Thread.sleep(), future.get() | future.get() (비동기지만 블로킹) |
논블로킹(Non-blocking) | Polling (while 문) | CompletableFuture.thenAccept() |
- 동기 + 블로킹: 호출한 함수가 끝날 때까지 기다리며, 다른 작업을 못 함
- 동기 + 논블로킹: 함수 호출 후 바로 반환하지만, 주기적으로 상태 확인 (Polling)
- 비동기 + 블로킹: 별도 스레드에서 실행되지만, get() 호출 시 블로킹
- 비동기 + 논블로킹: 별도 스레드에서 실행 후, 콜백(thenAccept())을 사용해 논블로킹 처리
이제 개념이 확실히 정리되었을 거예요! 🚀
728x90
'Programming' 카테고리의 다른 글
스프링부트 서비스 리소스 절감 최적화 전략 (0) | 2025.03.20 |
---|---|
GraalVM을 사용한 네이티브 이미지 정적 링크 빌드란? (0) | 2025.03.20 |
자바 WebClient VS FeignClient 비교 (0) | 2025.03.20 |
Kotlin + Spring Boot REST API 예시 (0) | 2025.03.18 |
Spring WebFlux: 비동기 논블로킹 API 개발 (0) | 2025.03.18 |