자바(SE)

[Java]Thread의 선/후 작업과 CountDownLatch

  • -

Thread의 선후 작업과 CountDownLatch

일련의 작업을 Thread로 구성했을 때 선/후 관계가 있는 경우가 왕왕 있다. 이때 하위 Thread의 작업이 완료될 때까지 main Thread가 기다려야 하는데 이때 join()이 사용된다. 아래의 경우를 살펴보자. 

     void useJoin() throws InterruptedException {
        List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Thread t = new SubThread();
            threads.add(t);
            t.start();
        }
        // t가 끝날 때까지 대기할 것!!
        for(Thread t: threads) {
            t.join();
        }

        System.out.println("완전 종료됨");
    }

     class SubThread extends Thread {
        @Override
        public void run() {
            try {
                Thread.sleep(new Random().nextInt(10) * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "종료");
        }
    }

필요하다면 join 메서드 호출 시 대기할 시간을 주기도 한다.

 

CountDownLatch 활용

위의 join 동작을 간단히 처리할 수 있는 클래스 CountDownLatch라는 녀석이 JDK 1.5 버전부터 있는데 한번 사용해보자.

Latch는 걸쇠라는 뜻이다. CountDonw이 완료될 때 까지 잡아놓겠다는 뜻일까나??

CountDownLatch는 몇 번 카운트 다운 할것인지를 인자로 생성할 수 있다. 스레드들이 종료되면서 latch의 카운트 다운을 1씩 줄이다가 0이 되는 순간 latch가 종료된다.

CountDownLatch latch = new CountDownLatch(5);

 

CountDownLatch가 사용된 예를 살펴보자. SubThread2는 종료되면서 latch의 countDown()을 호출하는데 이때마다 latch를 생성하면서 주엇던 count가 1씩 감소한다.

     class SubThread2 extends Thread {
        @Override
        public void run() {
            try {
                Thread.sleep(new Random().nextInt(10) * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // latch의 카운트를 1 줄인다.
            latch.countDown();
            System.out.println(Thread.currentThread().getName() + "종료");
        }
    }

 

main thread에서는 countdown이 0이 될 때 다음 동작을 하거나 특정 시간을 기다린 후 다음 동작을 수행할 수 있다.

     void join2() throws InterruptedException {
        List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Thread t = new SubThread2();
            threads.add(t);
            t.start();
        }
        // count가 0이 될때 까지 대기
        latch.await();
        // 설사 0이 되지 않더라도 3초간 대기 후 다음 동작으로 이동
        //latch.await(1000*3, TimeUnit.MILLISECONDS);
        System.out.println("완전 종료됨 2");
    }

 

즉 await()는 count가 0이 될 때까지 기다리는 메서드이다. await(long timeout, TimeUnit unit)은 설사 count가 0이 되지 않더라도 주어진 timeout 시간이 종료되면 다음 동작으로 이동한다.

 

'자바(SE)' 카테고리의 다른 글

[java] Skip "synthetic" methods when stepping  (0) 2022.04.03
[Java]List의 subList 살펴보기!  (2) 2022.02.10
Comparing identical expressions  (0) 2021.01.16
Annotation(에너테이션) 사용법  (0) 2020.10.20
밑이 2인 로그 구하기  (0) 2020.10.16
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.