java / / 2023. 10. 10. 19:55

사용 중인 Thread 사용 종료 후 main Thread 종료하기

테스트 케이스 작성 시 여러 Thread를 사용하는 경우가 있다.

여러 Thread가 실행되기 전에 테스트 실행이 끝나버리는 문제가 있는데 어떻게 해결할 수 있는지 알아보자.

예제 코드

public class CountDownLatchTest {

  static class UserThread extends Thread {
        private String id;

        public UserThread(String id) {
            this.id = id;
        }

        @Override
        public void run() {
            User user = new User();
            user.register(id);
        }
    }

  static class User {
        public void register(String id) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            System.out.println("registered id=" + id);
        }
    }
}

위에서 사용자를 등록하는 시간은 1초가 걸린다. 등록이 완료되면 registered id={id} 값이 출력된다.

1. 기본 실행

2개의 Thread가 동시에 사용자 등록을 한다.

    @Test
    public void test() {
        Thread thread1 = new UserThread("1");
        Thread thread2 = new UserThread("2");

        thread1.start();
        thread2.start();
    }
실행 결과

실행을 하면 아무 응답값도 출력되지 않는다.

그 이유는 Thread 실행이 종료되기 전에 main Thread가 종료되기 때문이다.

2. join 사용

위와 동일한 테스트이지만 Thread가 종료할 때까지 대기하는 join()을 사용한다.

thread1.join()을 사용하면 thread1을 실행시킨 main Thread는 thread1이 종료될 때까지 대기한다.

    @Test
    public void testWithJoin() throws InterruptedException {
        Thread thread1 = new UserThread("1");
        Thread thread2 = new UserThread("2");

        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
    }
실행 결과
registered id=2
registered id=1

CountDownLatch 사용

CountDownLatch는 일정 개수의 쓰레드가 끝난 후에 다음 Thread가 실행할 수 있도록 대기시키는 역할을 한다.

CountDownLatch를 구현하기 위한 새로운 Thread 클래스를 생성한다.

static class UserThreadWithCountDownLatch extends Thread {
        private String id;

        private CountDownLatch latch;

        public UserThreadWithCountDownLatch(String id, CountDownLatch latch) {
            this.id = id;
            this.latch = latch;
        }

        @Override
        public void run() {
            User user = new User();
            user.register(id);
            latch.countDown(); // 쓰레드가 끝날 때마다 카운트를 감소한다.
        }
    }

그리고 테스트를 작성한다.

    @Test
    public void testWithCountDownLatch() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(2); // 최대 2개의 쓰레드 실행
        Thread thread1 = new Thread(registerUser("1", latch));
        Thread thread2 = new Thread(registerUser("2", latch));

        thread1.start();
        thread2.start();

        latch.await(); // 쓰레드가 0이 되면 대기가 풀리고 다음 쓰레드가 실행이 된다. 즉, main 쓰레드가 실행된다.
    }
실행 결과
registered id=2
registered id=1
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유