개발 관련/Java

[JAVA:병렬 프로그래밍 - 2] CyclicBarrier 사용하기.

snoworca 2014. 9. 2. 11:13

  CyclicBarrier 를 사용하면 동시에 실행되는 쓰레드 내부 원하는 지점에서 대기를 걸어주고 모든 쓰레드가 대기 상태에 들어갔을때, 대기를 풀어주는 동작을 할 수 있다. 

    예를들어 설명하면 N 개의 쓰레드가 돌고 있다고 가정하고 CyclicBarrier 를 생성할 때 인자값으로 N 을 준다. 각각의 쓰레드 내에서 CyclicBarrier 의 await() 를 호출하고 호출 횟수가 N번에 도달했을 때, N개의 모든 쓰레드의 대기 상태가 해제된다.   


   아래 그림 참고. 설명이 조금 애매한데, 그냥 대충 보고 눈치것 이해하는 것이 좋다. 

   





CyclicBarrier를 활용한 예제코드:

public class main { private final static int THREADS = 5; private static CyclicBarrier cyclicBarrier = new CyclicBarrier(THREADS); public static class RandomSleepRunnable implements Runnable { private int id = 0; private static Random random = new Random(System.currentTimeMillis()); public RandomSleepRunnable(int id) { this.id = id; } @Override public void run() { System.out.println("Thread(" + id + ") : Start."); // 1000ms 에서 2000ms 사이의 딜레이 값을 랜덤하게 생성. int delay = random.nextInt(1001) + 1000; try { System.out.println("Thread(" + id + ") : Sleep " + delay + "ms"); // 랜덤하게 주어진 값을 이용하여 딜레이를 준다. Thread.sleep(delay); System.out.println("Thread(" + id + ") : End Sleep"); } catch (InterruptedException e) { e.printStackTrace(); } try { // 대기. cyclicBarrier 를 생성할 때, 인자값으로 준 count 개수만큼 // await를 호출한다면 모든 쓰레드의 wait 상태가 종료된다. cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } System.out.println("Thread(" + id + ") : End."); } } public static void main(String[] args) { // 쓰레드를 10개 생성. for(int i = 0; i < THREADS; ++i) { new Thread(new RandomSleepRunnable(i)).start(); } } }



결과:

Thread(0) : Start.
Thread(2) : Start.
Thread(2) : Sleep 1128ms
Thread(0) : Sleep 1205ms
Thread(1) : Start.
Thread(1) : Sleep 1968ms
Thread(4) : Start.
Thread(3) : Start.
Thread(4) : Sleep 1834ms
Thread(3) : Sleep 1020ms
Thread(3) : End Sleep
Thread(2) : End Sleep
Thread(0) : End Sleep
Thread(4) : End Sleep
Thread(1) : End Sleep
Thread(1) : End.
Thread(3) : End.
Thread(4) : End.
Thread(0) : End.
Thread(2) : End.