WEB개발/JAVA

CyclicBarrier, CountDownLatch

wooyeon06 2025. 2. 21. 10:48

`CyclicBarrier` 는 여러 개의 스레드가 모두 특정 지점(Barrier)에 도달할 때까지 기다렸다가, 동시에 실행을 재개하도록 하는 동기화 도구입니다.

  • "Cyclic"이라는 이름처럼 반복해서(barrier를 다시 사용할 수 있음) 사용할 수 있음
  • CountDownLatch와 달리 모든 스레드가 도착해야만 다음 단계로 진행

 

package com.example;

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierReuseExample {
    public static void main(String[] args) {
        int numThreads = 3;
        CyclicBarrier barrier = new CyclicBarrier(numThreads, () -> {
            System.out.println("모든 스레드가 도착함! 새로운 작업 시작!");
        });

        for (int i = 0; i < numThreads; i++) {
            new Thread(new ReusableWorker(barrier)).start();
        }
    }
}

class ReusableWorker implements Runnable {
    private final CyclicBarrier barrier;

    public ReusableWorker(CyclicBarrier barrier) {
        this.barrier = barrier;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName() + " 첫 번째 작업...");
            Thread.sleep((long) (Math.random() * 2000));
            barrier.await(); // 첫 번째 Barrier 도착

            System.out.println(Thread.currentThread().getName() + " 두 번째 작업...");
            Thread.sleep((long) (Math.random() * 2000));
            barrier.await(); // 두 번째 Barrier 도착
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

 

 

`CountDownLatch`는 여러 개의 작업이 완료될 때까지 기다리는 메커니즘을 제공하는 Java 동기화 클래스입니다.
일정 개수의 작업이 완료될 때까지 쓰레드를 대기 상태로 유지하고, 모든 작업이 완료되면 대기 중인 쓰레드들을 한꺼번에 실행합니다.

package com.example;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        int numWorkers = 3; // 작업자 수
        CountDownLatch latch = new CountDownLatch(numWorkers);

        for (int i = 0; i < numWorkers; i++) {
            new Thread(new Worker(latch), "Worker-" + i).start();
        }

        System.out.println("메인 쓰레드: 작업자들이 완료될 때까지 대기 중...");

        latch.await(); // 모든 작업이 끝날 때까지 대기

        System.out.println("메인 쓰레드: 모든 작업 완료됨, 다음 단계 진행!");
    }
}

class Worker implements Runnable {
    private final CountDownLatch latch;

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

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName() + " 작업 시작...");
            Thread.sleep((long) (Math.random() * 3000)); // 작업 시뮬레이션
            System.out.println(Thread.currentThread().getName() + " 작업 완료!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            latch.countDown(); // 작업 완료 후 count 감소
        }
    }
}