728x90
CountDownLatch
숫자세는 걸쇠
CountDownLatch 는 언제 사용 할까
쓰레드를 N개 실행했을 때, 일정 개수의 쓰레드가 모두 끝날 때 까지 기다려야지만 다음으로 진행할 수 있거나 다른 쓰레드를 실행 시킬 수 있는 경우 사용한다. 예를들어서 리스트에 어떤 자료구조가 있고, 각 자료구조를 병렬로 처리한 후 배치(batch)로 데이터 베이스를 업데이트 한다거나 다른 시스템으로 push하는 경우가 있다.
CountDownLatch 어떻게 사용 할까 ?
CountDownLatch latch = new CountDownLatch(N);
// 횟수 차감
latch.countDown();
//모든 작업이 끝난 후 실행시켜 주세요
latch.await();
CountDownLatch를 초기화 할 때 정수값 count를 넣어준다. 쓰레드는 마지막에서 countDown() 메서드를 불러준다. 그러면 초 기화 때 넣어준 정수값이 하나 내려간다.
즉 각 쓰레드는 마지막에서 자신이 실행완료 했음을 countDown() 메서드로 알려준다.
countDown() 메서드로 스레드 호출 값이 0까지 도달 했다면, 스레드들이 끝나고 수행해야될 메서드에 await()메서드를 불러준다.
카운트다운이 완료되면 게이트(latch)가 열리는 것이다.
Code
public class CountT {
int count = 1;
public void call() {
System.out.println("count = " + this.count++);
}
}
@Test
void CountDownLatch() throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(5);
CountT tt = new CountT();
for (int i = 1; i <= 5; i++) {
executorService.execute(() -> {
tt.call();
});
}
System.out.println("메인 스레드");
}
for 문을 모두 돌고 난 후 마지막 sout의 "메인 스레드" 가 호출 될 것을 기대 할 것이다.
메인 스레드
count = 1
count = 3
count = 5
count = 2
count = 4
하지마 위 코드의 결과는 메인 스레드가 먼저 실행되버린다.
for문이 너무 찰나의 순간이기 때문이다.
하지만 CountDownLatch를 사용하면, 아래와 같이 5개의 쓰레드가 완료된 후 메인 스레드가 실행된다.
- new CountDownLatch(5) : 몇개의 스레드가 끝나면 다음 스레드를 시작할지 정한다. 5개를 설정했다.
- countDownLatch.countDown() : 스레드가 끝날 때 마다 카운트를 감소한다.
- countDownLatch.await() : 카운트가 0이되면 대기가 풀리고 이후 스레드가 실행되게 된다.
@Test
void CountDownLatch() throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(5);
int iterateCount = 5;
CountDownLatch countDownLatch = new CountDownLatch(iterateCount);
CountT tt = new CountT();
for (int i = 1; i <= iterateCount; i++) {
executorService.execute(() -> {
tt.call();
//countDownLatch의 카운트 5 - 1
countDownLatch.countDown();
});
}
countDownLatch.await();
System.out.println("메인 스레드");
}
count = 1
count = 5
count = 2
count = 3
count = 4
메인 스레드
결과는 메인스레드가 for 문이 끝난 후 잘 실행 되는것을 확인할 수 있다.
728x90
'개-발 > Java + Spring + Kotlin' 카테고리의 다른 글
[Kotlin] 단위 테스트 작성하기 (feat.JUnit5 , MockK) (0) | 2024.02.21 |
---|---|
[Spring Batch] addBatch로 다량 쿼리문 한번에 실행 (bulk insert) (0) | 2024.01.17 |
[Spring] 선착순 이벤트 구현 ( 동시성 Pessimistic Lock) (3) | 2024.01.04 |
[Spring] @Constraint로 커스텀 Vaildatation 만들기 (0) | 2023.12.27 |
[Spring] AOP 를 활용한 중복요청 방지 (따닥방지) (2) | 2023.12.19 |