CS 정리

Java 대용량 데이터 처리 (6) - 멀티 쓰래드/병렬 처리

문쿼리 2025. 5. 4. 16:23

6. 싱글 쓰레드 → 멀티 쓰레드 / 병렬 처리 (10만 명에게 알림 발송)

싱글 쓰레드 vs 멀티 쓰레드/병렬 처리

  • 싱글 쓰레드 방식은 하나의 작업 흐름으로 모든 알림을 순차적으로 처리.
    사용자는 많고, 각 알림 발송 시간이 지연되면 전체 처리 시간도 길어짐.
  • 멀티 쓰레드 / 병렬 처리는 여러 쓰레드를 활용해 동시에 알림을 전송.
    작업을 분산해 처리 속도를 높이고, 전체 처리 시간을 획기적으로 단축할 수 있음.

비동기 병렬 처리 예제

Bad case: 싱글 쓰레드

public class NotificationService {
    public void sendNotifications(List<String> users) {
        for (String user : users) {
            send(user);  // 한 명씩 순차 처리
        }
    }

    private void send(String user) {
        System.out.println("Sending to " + user);
        try {
            Thread.sleep(1000);  // 발송 지연 시뮬레이션
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

사용자 수가 30,000명인 경우 예상 작업 시간 : 30,000초 = 500분 = 8시간 20분

 

Good case: 멀티 쓰레드 (ThreadPool 사용)

public class NotificationService {
    private final ExecutorService executor = Executors.newFixedThreadPool(10); // 병렬로 10개 작업

    public void sendNotifications(List<String> users) {
        for (String user : users) {
            executor.submit(() -> send(user));
        }
        executor.shutdown();
    }

    private void send(String user) {
        System.out.println("Sending to " + user);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

사용자 수가 30,000명인 경우 예상 작업 시간 : 30,000/10초 = 50분

요약 정리

  • 싱글 쓰레드는 작업이 많을수록 느림
    → 알림 10만 건을 순차로 보내면 수 시간이 걸릴 수 있음
  • 멀티 쓰레드는 작업을 나눠 동시에 처리, 처리 속도 향상
  • 실무에서는 ExecutorService, CompletableFuture, 또는 Spring @Async 등을 활용
  • 병렬 처리 시 스레드풀 관리, 예외 처리, 리소스 경쟁에 주의 필요

주의사항

  • 스레드 수는 CPU/메모리 상황에 맞게 설정해야 함 (과도하면 오히려 느려짐)
  • 스레드 풀은 반드시 shutdown() 해야 리소스 누수 방지
  • 실패 처리(재시도, 로깅 등) 및 타임아웃 관리가 필수
  • 사용자 수가 너무 많으면 배치 분할 처리도 고려 (ex. 1000명 단위로 나눠 처리)