기술 블로그

CountDownLatch 본문

JAVA

CountDownLatch

parkit 2025. 4. 10. 23:11
728x90
반응형

CountDownLatch는 Java의 동시성 프레임워크에서 제공하는 동기화 도구로, 하나 이상의 스레드가 다른 스레드들의 작업이 완료될 때까지 기다릴 수 있게 해주는 메커니즘입니다. 이 클래스는 java.util.concurrent 패키지에 속해 있습니다.

기본 개념

  • 카운트다운 메커니즘: 초기 카운트 값에서 시작해 0에 도달할 때까지 감소
  • 대기 기능: 카운트가 0이 될 때까지 스레드들을 차단(블로킹)
  • 일회성: 한 번 카운트가 0에 도달하면 재설정할 수 없음

주요 메서드

  1. 생성자:
    • CountDownLatch(int count): 지정된 카운트 값으로 래치 초기화
  2. countDown():
    • 카운트를 1 감소시킴
    • 카운트가 0에 도달하면 대기 중인 모든 스레드를 해제
  3. await():
    • 카운트가 0이 될 때까지 현재 스레드를 차단
    • 오버로딩 버전:
      • await(): 카운트가 0이 될 때까지 무기한 대기
      • await(long timeout, TimeUnit unit): 지정된 시간 동안만 대기

예시 코드

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        // 3개의 작업을 기다리는 CountDownLatch 생성
        CountDownLatch latch = new CountDownLatch(3);
        
        // 3개의 스레드를 가진 스레드 풀 생성
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        System.out.println("메인 스레드: 작업 시작");
        
        for (int i = 0; i < 3; i++) {
            final int workerId = i;
            executor.submit(() -> {
                try {
                    // 작업 시뮬레이션
                    System.out.println("작업자 " + workerId + ": 작업 시작");
                    Thread.sleep(2000); // 작업에 2초 소요
                    System.out.println("작업자 " + workerId + ": 작업 완료");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    // 작업 완료 후 카운트다운
                    latch.countDown();
                    System.out.println("작업자 " + workerId + ": 카운트다운. 남은 카운트: " + latch.getCount());
                }
            });
        }
        
        // 모든 작업이 완료될 때까지 메인 스레드 대기
        System.out.println("메인 스레드: 모든 작업 완료 대기 중...");
        latch.await();
        System.out.println("메인 스레드: 모든 작업 완료됨. 다음 단계로 진행합니다.");
        
        // 스레드 풀 종료
        executor.shutdown();
    }
}

 

실행 결과 설명

이 코드를 실행하면 다음과 같은 결과가 나타납니다:

메인 스레드: 작업 시작
메인 스레드: 모든 작업 완료 대기 중...
작업자 0: 작업 시작
작업자 1: 작업 시작
작업자 2: 작업 시작
작업자 0: 작업 완료
작업자 0: 카운트다운. 남은 카운트: 2
작업자 2: 작업 완료
작업자 2: 카운트다운. 남은 카운트: 1
작업자 1: 작업 완료
작업자 1: 카운트다운. 남은 카운트: 0
메인 스레드: 모든 작업 완료됨. 다음 단계로 진행합니다.

 

실행 과정 설명:

  1. 메인 스레드가 카운트가 3인 CountDownLatch를 생성합니다.
  2. 세 개의 작업자 스레드를 생성하고 실행합니다.
  3. 메인 스레드는 latch.await()를 호출하여 모든 작업이 완료될 때까지 대기합니다.
  4. 각 작업자 스레드는 작업을 완료한 후 latch.countDown()을 호출하여 카운트를 감소시킵니다.
  5. 마지막 작업자가 countDown()을 호출하면 카운트가 0이 되고, 대기 중이던 메인 스레드가 해제됩니다.
  6. 메인 스레드는 작업 완료 메시지를 출력하고 진행을 계속합니다.

주요 특징

  1. 동기화 메커니즘: 여러 스레드 간의 작업 완료를 동기화할 수 있습니다.
  2. 스타트 신호로 사용: 카운트가 1인 래치를 사용하여 여러 스레드를 동시에 시작할 수 있습니다.
  3. 일회성 장벽: 한 번 카운트가 0에 도달하면 래치는 리셋할 수 없습니다. 다시 사용하려면 새 인스턴스를 생성해야 합니다.
  4. 인터럽트 감지: await() 메서드는 인터럽트를 감지하고 InterruptedException을 발생시킬 수 있습니다.

CountDownLatch는 병렬 처리 작업을 조율할 때, 특히 여러 작업이 완료될 때까지 기다려야 하는 상황에서 매우 유용합니다. 예를 들어, 서비스 초기화, 테스트 실행, 병렬 계산 등에 활용됩니다.

 

 

 

 

728x90
반응형