java
병렬 처리 - CountDownLatch
dev-lab
2020. 11. 16. 13:02
반응형
쓰레드를 사용해서 동시에 여러가지 작업을 하는 경우가 있다.
하지만 쓰레드는 비동기 처리이기 때문에 메인 쓰레드와 같이 작업이 진행되고 매번 처리되는 순서도 달라진다.
실행시킨 쓰레드가 모두 처리되었을 때 다시 메인 쓰레드의 동작이 실행되도록 하는 방법은 없을까 찾아보던 중
CountDownLatch 클래스를 활용하면 위의 문제를 해결할 수 있다는 걸 알게 되어 정리하는 글을 작성하게 되었다.
CountDownLatch는 선언 시 매개변수를 하나 받는데 해당 매개변수는 정수이다.
핵심은 countDown() 메소드와 await() 메소드인데 각각의 쓰레드에서 countDown() 메소드를 호출하면 처음 선언할 때 받은 변수의 값이 하나씩 떨어진다.
await()를 사용 시 프로그램은 CountDownLatch가 최초 선언 시 입력 받은 count가 0이 될때까지 대기상대가 된다.
쓰레드가 count를 떨어뜨려 0이 되면 프로그램이 실행되 프로그램의 sync를 맞출 수 있게 된다.
소스코드
import java.util.concurrent.CountDownLatch;
import java.util.stream.IntStream;
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
CountDownLatchTest t = new CountDownLatchTest();
t.runWorkers();
}
private void runWorkers() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(5);
IntStream.range(0, 5)
.mapToObj(i -> new Worker(countDownLatch, i))
.map(Thread::new)
.forEach(Thread::start);
countDownLatch.await();
System.out.println("mainThread end");
}
private static class Worker implements Runnable{
private CountDownLatch countDownLatch;
private int idx;
public Worker(CountDownLatch countDownLatch, int idx) {
super();
this.countDownLatch = countDownLatch;
this.idx = idx;
}
@Override
public void run() {
System.out.println(idx + "-thread start");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
System.out.println(idx + "-thread end");
countDownLatch.countDown();
}
}
}
}
실행결과
0-thread start 4-thread start 3-thread start 2-thread start 1-thread start 3-thread end 1-thread end 2-thread end 4-thread end 0-thread end mainThread end |
개인적으로 javascript의 async await 기능과 매우 흡사하다는 느낌을 받았습니다.
반응형