테스트 케이스 작성 시 여러 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
반응형