CountDownLatch

Seung jun Cha·2023년 7월 16일
0

1. 개념

  • 멀티스레드 환경에서 동기화를 위해 사용되는 도구입니다. 다른 스레드들이(주로 메인스레드가) 하나 이상의 스레드가 특정 작업을 마치기를 기다리는 상황에서 유용하게 사용됩니다.
    예를 들어, 메인 스레드에서 스레드들을 생성하고 시작한 뒤, 스레드들이 특정 작업을 완료할 때까지 메인 스레드가 기다리는 상황 또는 일정 시간을 초과할 경우 작업을 기다리지 않도록 하는 상황이다.
    • 하나 이상의 스레드가 특정 작업을 수행하고, 다른 스레드들은 해당 작업이 완료될 때까지 기다려야 할 때.
    • 특정 스레드가 여러 작업을 병렬로 수행하고, 다른 스레드들은 이 작업들이 모두 완료될 때까지 기다려야 할 때.
  • CountDownLatch는 카운트 값을 가지고 초기화됩니다. 이 카운트 값은 카운트다운이 완료되기 위해 필요한 작업의 수를 의미합니다. 각 스레드는 특정 작업을 수행한 뒤, CountDownLatch의 countDown() 메서드를 호출하여 카운트 값을 하나 감소시킵니다. 다른 스레드들은 await() 메서드를 호출하여 카운트가 0이 될 때까지 기다립니다.

2. 작동과정

  1. CountDownLatch 객체를 초기화할 때 카운트 값을 설정합니다. CountDownLatch의 생성자로 전달되는 숫자는 실행할 스레드의 개수를 나타냅니다.
CountDownLatch countDownLatch = new CountDownLatch(5);
  1. 주 스레드나 특정 스레드가 작업을 시작합니다.

  2. 작업이 완료되면 해당 스레드는 CountDownLatch의 countDown() 메서드를 호출하여 카운트 값을 감소시킵니다.

countDownLatch.countDown();
  1. 다른 스레드들은 await() 메서드를 호출하여 CountDownLatch의 값이 0이 될 때까지 대기합니다.
countDownLatch.await();
  1. 카운트 값이 0이 되면 다른 스레드들이 동작한다.
public class CountDownLatchExample {

    public static void main(String args[]) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        List<Thread> workers = Stream
                .generate(() -> new Thread(new Worker(countDownLatch)))
                .limit(5)
                .collect(toList());
--------------------------------------------------------
ExecutorService는 스레드를 자동으로 관리해주기 때문에 
new Thread 같은 별도로 스레드를 생성하고 시작하는 과정을 직접 구현하지 않아도 됩니다.
 for (int i = 0; i < numThreads; i++) {
            executorService.submit(new Worker(countDownLatch));
        }
--------------------------------------------------------
        System.out.println("Start multi threads (tid: "
                + Thread.currentThread().getId() + ")");

        workers.forEach(Thread::start);

        System.out.println("Waiting for some work to be finished (tid: "
                + Thread.currentThread().getId() + ")");

        countDownLatch.await(); // 메인스레드는 Latch가 0이 될때 까지 대기

        System.out.println("Finished (tid: "
                + Thread.currentThread().getId() + ")");
    }

    public static class Worker implements Runnable {
        private CountDownLatch countDownLatch;

        public Worker(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            System.out.println("Do something (tid: " + Thread.currentThread().getId() + ")");
            countDownLatch.countDown();
        }
    }
}

0개의 댓글