카테고리 없음

비동기 처리, 병렬 처리, BFS/DFS 탐색

iamhyeon 2025. 12. 7. 18:35

 

웹 서비스, 분산 시스템, 대규모 데이터 처리 등 대부분의 애플리케이션은 동시에 여러 작업을 처리해야 한다.
이때 사용되는 개념이 비동기 처리(Asynchronous), 병렬 처리(Parallel)이다.

 

1. 비동기 처리 (Asynchronous Processing)

비동기 처리는 작업을 요청한 후 그 결과를 기다리지 않고 다음 작업을 실행하는 방식이다.

예시

  • 웹 서버에서 이메일 전송 요청 → 메인 요청 응답과 분리하여 비동기로 처리
  • 이미지/영상 파일 업로드 후 변환 작업을 백그라운드에서 실행
  • 프론트엔드에서 fetch 요청 후 UI는 계속 작동

비동기 처리는 주로 I/O 작업 처리에 최적화되어 있다.

네트워크 호출, DB 응답, 파일 읽기/쓰기 등은 CPU보다 속도가 느리므로
메인 스레드가 기다리지 않고 다른 일을 처리하도록 해야 효율적이다.

비동기 처리의 장점

  • 응답 지연(Blocking) 없이 빠른 사용자 경험 제공
  • 스레드 낭비 없음
  • 높은 처리량(Throughput) 확보 가능

자바에서의 비동기 처리 예시 (CompletableFuture)

CompletableFuture.supplyAsync(() -> {
    return callExternalApi();
}).thenAccept(result -> {
    System.out.println("API 결과 처리: " + result);
});

비동기는 “스레드를 여러 개 쓰는가?”가 중요한 것이 아니라,
현재 흐름을 멈추지 않고 진행하는가가 중요하다.

 

2. 병렬 처리 (Parallel Processing)

병렬 처리는 여러 CPU 코어가 실제로 동시에 여러 작업을 실행하는 것을 의미한다.

비동기 = 기다리지 않는 것
병렬 처리 = 실제 동시에 실행되는 것

둘은 서로 다르지만 함께 사용할 수 있다.

병렬 처리의 활용 사례

  • 대용량 데이터 분석
  • 이미지 변환, 압축, 암호화
  • 머신러닝 연산
  • 대규모 Simulation 처리

병렬 처리 예시 (Java Parallel Stream)

list.parallelStream()
    .map(this::heavyCalculation)
    .collect(Collectors.toList());

CPU 코어 수만큼 스레드를 분배하여 실제로 병렬 실행되는 구조이다.

 

3. BFS(너비 우선 탐색) — 병렬 확장의 대표적 구조

BFS란?

그래프나 트리 구조에서 가까운 노드부터 탐색해 나가는 방식이다.
큐(Queue)를 사용하며, “동시에 여러 방향으로 확장되는 탐색”과 유사하다.

BFS 예시 코드

Queue<Node> queue = new LinkedList<>();
queue.add(start);

while (!queue.isEmpty()) {
    Node current = queue.poll();
    for (Node next : current.neighbors()) {
        if (!visited.contains(next)) {
            visited.add(next);
            queue.add(next);
        }
    }
}

BFS의 특징

  • 가장 짧은 거리 문제에 최적
  • 모든 자식 노드를 동일한 깊이에서 먼저 탐색
  • 너비가 많을수록 메모리 사용량이 증가

BFS는 병렬적 사고와 맞닿아 있다

BFS는 이론적으로 각 Level 노드를 병렬로 탐색할 수 있다.

예:

  • 그래프에서 “1단계 이웃”, “2단계 이웃”…을 동시에 스캔
  • 실제 분산 시스템에서는 BFS 방식 탐색을 병렬 Map-Reduce로 구현하기도 한다

 

4. DFS(깊이 우선 탐색) — 재귀적, 순차적 확장 방식

한 방향으로 깊게 들어갔다가, 막히면 되돌아오는 방식으로 탐색한다.
스택(Stack) 또는 재귀 함수로 구현한다.

DFS 예시 코드

void dfs(Node node) {
    visited.add(node);
    for (Node next : node.neighbors()) {
        if (!visited.contains(next)) {
            dfs(next);
        }
    }
}

DFS 특징

  • 구현이 단순하고 재귀적으로 표현 가능
  • 백트래킹(backtracking)에 강함
  • 길찾기, 순열/조합, 완전 탐색 문제에 자주 사용

DFS는 순차적이며 병렬과 반대처럼 보이지만,

각 분기를 병렬 스레드에 할당하면 "완전 탐색 병렬화"가 가능하다.

예:

  • 게임 AI 탐색
  • 경로 탐색 알고리즘 병렬 최적화
  • 분기한정법(Branch and Bound)

 

5. 비동기·병렬 처리와 BFS·DFS를 함께 이해하기

이 네 가지 개념은 사실 “동시에 처리한다”는 관점에서 서로 연결된다.

연결 방식 요약

  • 비동기 처리: 호출한 후 기다리지 않는다 → 흐름 제어 방식
  • 병렬 처리: 실제로 동시에 실행한다 → 실행 방식
  • BFS: 동시에 여러 노드를 펼쳐보는 구조(병렬적 성향 강함)
  • DFS: 깊이 우선으로 탐색하는 구조(순차적 성향 강함 → 필요 시 병렬 확장 가능)

예시 시나리오: 대규모 그래프 탐색 엔진

  • BFS Level 단위를 병렬 스레드로 분배
  • 각 노드 탐색은 비동기 API 호출
  • 일부 탐색은 DFS 기반으로 깊이 우선 방식 적용
    이러한 구조는 실제 검색 엔진, 소셜 그래프 분석 등에서 사용된다.

 

 

반응형