JAVA

Blocking vs Non-Blocking, Synchronous vs Asynchronous

icedstone 2025. 4. 21. 21:36
반응형

 

 

구분 Blocking Non-Blocking Synchronous Asynchronous
의미 요청이 끝날 때까지 기다림 요청하고 바로 제어권 반환 호출자가 결과를 직접 기다림 호출 후 결과는 콜백/이벤트로 전달됨
예시 파일 읽기 완료까지 멈춤 읽을 게 없으면 즉시 리턴 A → B → 결과 기다림 → 다음 A → B 호출만 하고 → 다음 코드 실행
대표 상황 전통 IO NIO 일반 함수 호출 Future, Callback, Reactor

 

위의 비교가 어렵다면 다음과 같이 비교해보도록 하자

Blocking vs Non-Blocking

작업이 끝날 때까지 기다릴 것이냐, 말 것이냐”의 차이
→ "작업 진입 시점의 차이"

Synchronous vs Asynchronous

결과를 직접 받느냐, 나중에 받느냐”의 차이
→ "작업 종료 시점의 처리 방식"

 

사실 이렇게 봐도 아직도 헷갈릴 수도 있다.

Blocking은 작업이 끝날 때 까지 기다리는데 Synchronous도 결과를 직접 받으려면 끝날 때 까지 기다려야 하는거 아니야?

당연히 가질 수 있는 의문이기에 실제로 조합을 해서 비교해보자

 

Blocking + Synchronous

public void approvePayment(PaymentRequest request) {
    // 외부 PG사 API 호출 - 결과가 올 때까지 블로킹
    PaymentResult result = paymentGatewayClient.send(request);

    if (!result.isSuccess()) {
        throw new PaymentFailedException("결제 실패");
    }

    // 결제 승인 후 주문 상태 업데이트 (동기 처리)
    orderService.updateStatus(request.getOrderId(), "PAID");
}

 

Non-Blocking + Synchronous

public void useCoupon(String couponId, String userId) {
    // 락 시도 - 실패하면 바로 false 리턴 (Non-blocking)
    boolean lockAcquired = redisLock.tryLock("coupon:" + couponId, 5);

    if (!lockAcquired) {
        throw new CouponAlreadyUsedException();
    }

    try {
        // 락 획득 후 쿠폰 사용 처리
        couponService.markAsUsed(couponId, userId);
    } finally {
        redisLock.release("coupon:" + couponId);
    }
}

 

Blocking + Asynchronous

public void sendEmailAndWait(String email, String message) {
    Future<Result> result = emailSend(email, message);

    try {
        Result emailResult = result.get(10, TimeUnit.SECONDS); // 결과 받을 때까지 블로킹
        if (emailResult.isSuccess()) {
            throw new EmailSendException();
        }
    } catch (Exception e) {
        throw new EmailSendException("이메일 발송 실패", e);
    }
}

 

Non-Blocking + Asynchronous

public void sendOrderNotification(User user, Order order) {
    // Kafka Producer를 통해 논블로킹으로 이벤트 전송
    NotificationEvent event = new NotificationEvent(user.getId(), order.getId(), "주문 완료");
    
    kafkaTemplate.send("notification-topic", event) // 즉시 반환됨
        .addCallback(
            success -> log.info("알림 이벤트 전송 성공"),
            failure -> log.error("알림 이벤트 전송 실패", failure)
        );

    // 응답 확인 없이 다음 로직 바로 진행 (비동기 + 논블로킹)
    log.debug("알림 전송 요청 완료");
}

 

올바른 예제 소스코드를 만든건지 나도 헷갈린다. 가장 중요한건 시점이라는걸 참고해서 보도록 하자.

blocking vs non-blocking은 결과가 나올 때 까지 기다리느냐?

synchronous vs asynchronous는 제어 흐름의 주체가 누구한테 있느냐?(이 말이 어렵다면 단순하게 결과물을 직접 받아서 쓰느냐? 정도로 받아들여보자)

반응형