How to Use CountDownLatch
정의
latch
- 최초 입력 한번 받아들이고 저장.
- 후속 입력으로 입력 이전상태 복원.
사용방법
- 생성자(count) 하나 지정하면서 인스턴스 생성
countDown()
호출하여 생성자 count– 처리await()
호출하여count = 0
될때까지 메인스레드 멈춰줌.- 메소드 코드 라인 수행 도중 정하고 싶은 시점에
countDown()
호출 - 하나의 JVM 프로세스 안에서 글로벌하게 공유되는 LatchCount 인스턴스임.
- 메인스레드와 스레드 병렬 작업 수행간 작업 시작과 종료시점을 제어할 수 있음.
- Worker 스레드 모두 작업 끝마친 후 메인 실행 시키고 싶을때
- 메인스레드와 스레드 병렬 작업 수행간 작업 시작과 종료시점을 제어할 수 있음.
예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package org.example;
import java.util.concurrent.CountDownLatch;
public class Driver {
public static void main(String[] args) throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1); // worker들을 일괄 실행시킬려고 생성
CountDownLatch doneSignal = new CountDownLatch(5); // worker들 갯수, 각 worker가 작업 끝내면 countDown() 호출
for (int i = 0; i < 5; ++i) // create and start threads
new Thread(new Worker(startSignal, doneSignal)).start();
System.out.println("all worker thread started, but all worker won't process before you call startSignal.countDown() below");
doSomethingElse(); // 이 라인 실행동안 Worker가 await()에 걸려 다음 라인 실행못함.
startSignal.countDown(); // for로 생성한 스레드를 이때 모두 진행시킴 (startSignal을 0을 만듬으로써)
// CountDownLatch 가 프로세스 글로벌 하게 공유되는 int임을 알 수 있음.
doneSignal.await(); // doneSignal 이 0 될때까지 기다림.
doSomethingElse();
System.out.println("==main end==");
}
private static void doSomethingElse() throws InterruptedException {
// 메인스레드에서 수행하는 작업 mockup : 1초 걸린다 가정
System.out.println("doSomethingElse start");
Thread.sleep(1000);
System.out.println("doSomethingElse end");
}
}
class Worker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
startSignal.await(); // main에서 지정한 startSignal.getCount() 0 될때까지 기다림
doWork();
doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
}
void doWork() throws InterruptedException {
System.out.println("working start");
Thread.sleep(1000);
System.out.println("working end");
}
}
나는 어디에 쓸수있겠나?
- API 서비스 레이어의 트랜잭션 데이터 무결성 검증 유닛 테스트
참고자료
This post is licensed under CC BY 4.0 by the author.