일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- jobdispatcher
- livedatam
- alarmanager
- Android
- workmanager
- firebase
- Service
- 빈
- epmty
- Job
- Library
- shceduler
- PHP
- jobschduler
- Background
- 검사
- schedule
- Today
- Total
에몽이
[JAVA:병렬 프로그래밍 - 1] CountDownLatch 사용하기. 본문
만약 백그라운드에서 실행되고 있는 싱글 쓰레드가 종료되기를 기다리는 코드를 작성해야 한다면 당장 Thread 클래스의 join() 메소드 부터 떠올리게 될 것이다. 아래와 같이 말이다.
간단한 join() 사용예:
Thread thread = new Thread() { @Override public void run() { System.out.println("start trhead."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("end trhead."); } }; thread.start(); try { // 스레드가 끝날때 까지 대기한다. thread.join(); } catch (InterruptedException e) { e.printStackTrace(); }System.out.println("Thread terminated.");
하지만, 멀티 쓰레드에서 모든 동작이 끝나기를 기다려야 하는 상황이라면 join 을 사용하기 조금 난감하다. 이럴 땐 CountDownLatch 를 사용하면 참 편리하다. (안드로이드 API 설명 페이지로 링크합니다. 이 곳이 오라클 페이지보다 보기 좋아서;; http://developer.android.com/reference/java/util/concurrent/CountDownLatch.html )
CountDownLatch 는 생성할 때 1 이상의 카운트를 인자값으로 받는다. 그리고 특정 메소드 내부에서 await() 메소드로 대기 상태를 만들어주고 CountDownLatch 를 생성할 때 설정한 count 가 0이 되기만들 기다렸다가 0이 되는 순간 대기 상태를 해제한다. 원리는 아래 그림과 같다.
예제코드를 살펴보면 아래와 같다.
CountDownLatch 를 활용한 예제코드:
public class main { private final static int THREADS = 10; private static CountDownLatch lacth = new CountDownLatch(THREADS); public static class RandomSleepRunnable implements Runnable { private int id = 0; private static Random random = new Random(System.currentTimeMillis()); public RandomSleepRunnable(int id) { this.id = id; } @Override public void run() { System.out.println("Thread(" + id + ") : Start."); // 1000ms 에서 2000ms 사이의 딜레이 값을 랜덤하게 생성. int delay = random.nextInt(1001) + 1000; try { System.out.println("Thread(" + id + ") : Sleep " + delay + "ms"); Thread.sleep(delay); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread(" + id + ") : End."); // lacth 의 카운터에서 -1. lacth.countDown(); } } public static void main(String[] args) { // 쓰레드를 10개 생성. for(int i = 0; i < THREADS; ++i) { new Thread(new RandomSleepRunnable(i)).start(); } try { // lacth 의 카운트가 0이 될 때 까지 대기한다. lacth.await(); // 아래와 같이 TimeOut 을 설정할 수 있다. // 아래의 경우는, 만약 2000ms 동안 latch 의 카운트가 0 되지 않는다면 // wait 상태를 해제하고 다음 동작으로 넘어간다. //lacth.await(2000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("All threads terminated."); } }
결과:
Thread(1) : Start. Thread(1) : Sleep 1267ms Thread(2) : Start. Thread(0) : Start. Thread(0) : Sleep 1168ms Thread(2) : Sleep 1085ms Thread(5) : Start. Thread(4) : Start. Thread(4) : Sleep 1573ms Thread(5) : Sleep 1868ms Thread(3) : Start. Thread(3) : Sleep 1552ms Thread(6) : Start. Thread(6) : Sleep 1869ms Thread(7) : Start. Thread(8) : Start. Thread(7) : Sleep 1001ms Thread(8) : Sleep 1636ms Thread(9) : Start. Thread(9) : Sleep 1573ms Thread(7) : End. Thread(2) : End. Thread(0) : End. Thread(1) : End. Thread(3) : End. Thread(4) : End. Thread(9) : End. Thread(8) : End. Thread(5) : End. Thread(6) : End. All threads terminated.
매우 간단하고 사용하기도 편리하다.
출처: http://dev.re.kr/52 [Dev.re.kr]
'java' 카테고리의 다른 글
[Java] 네트워크 (Network) - 개요, InetAddress, URL, URLConnection 클래스 [출처] [Java] 네트워크 (Network) - 개요, InetAddress, URL, URLConnection 클래스 (0) | 2017.07.04 |
---|---|
Java Generic 정리 (0) | 2017.07.04 |
Java Annotation: 인터페이스 강요로부터 자유를… (0) | 2017.07.04 |
우분투투 자바 컴파일하기 (0) | 2017.06.30 |
netty 재연결코드 (0) | 2017.06.30 |