1. 멀티스레드에서 서로 연산된 결과를 써야 하는 경우
만약 멀티스레드가 있을 경우 한 스레드가 다른 스레드에서 연산한 값을 가져와 연산을 해야할 때, 한 스레드가 다른 스레드의 연산결과를 기다리고 작업을 끝내야할 때가 있다.
[ex]
- main 스레드의 역할 = task1에서 계산한 값 + task2에서 계산한 값 ( 1부터 100까지의 합 )
- task1 스레드의 역할 = 1부터 50까지의 합
- task2 스레드 = 51부터 100까지의 합
이럴 경우에는 메인 스레드는 task1스레드와 task2스레드의 연산을 기다린 후 작업을 해야 정상적인 값이 나온다
※ 별도 처리 안하고 멀티스레드 각각 실행한다고 할 경우
task1, task2에서 연산을 끝내기도 전에 main 스레드가 연산한다면 결과는 0이 나올 것이다.
해결방법은
① 메인스레드를 sleep()하는 방법
② while(task1 != terminate)으로 작업이 끝날때까지 무한루프를 도는 방법
③ join을 쓰는 방법
①은 task1, task2 스레드가 끝날 타이밍을 맞추기가 어렵고,
②는 while 자체가 cpu를 써먹기 때문에 비효율적이다.
2. Join 사용
public class JoinMainV3 {
public static void main(String[] args) throws InterruptedException {
log("Start");
SumTask task1 = new SumTask(1, 50);
SumTask task2 = new SumTask(51, 100);
Thread thread1 = new Thread(task1, "thread-1");
Thread thread2 = new Thread(task2, "thread-2");
thread1.start();
thread2.start();
// join 사용 - 스레드가 종료될 때 까지 대기
thread1.join();
thread2.join(1000);
log("main스레드 대기 완료"); // thread1, thread2가 끝나자마자 메인스레드 대기 완료
log("task1.result = " + task1.result);
log("task2.result = " + task2.result);
int sumAll = task1.result + task2.result;
log("task1+task2 = " + sumAll);
log("End");
}
static class SumTask implements Runnable {
int startValue;
int endValue;
int result = 0;
public SumTask(int startValue, int endValue) {
this.startValue = startValue;
this.endValue = endValue;
}
@Override
public void run() {
log("작업시작");
for (int i = startValue; i < endValue; i++) {
result += i;
}
sleep(2000);
log("작업 완료 result = " + result);
}
}
}
스레드A.join(); -> 스레드A가 끝날때까지 Wait 했다가 끝나면 Runnable로 전환한다
- join() 메서드에 인수를 넣지 않으면 무한정 기다린다 = WATING
- join() 메서드에 인수(mills)를 넣는다면 특정시간까지 기다렸다가 그 시간까지 기다리는 스레드가 끝났던 아니던 무조건 스레드 wait 상태를 풀어버린다 = TIMED_WATING
김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성 강의 | 김영한 - 인프런
김영한 | 멀티스레드와 동시성을 기초부터 실무 레벨까지 깊이있게 학습합니다., 국내 개발 분야 누적 수강생 1위, 제대로 만든 김영한의 실전 자바[사진][임베딩 영상]단순히 자바 문법을 안다?
www.inflearn.com
'JAVA' 카테고리의 다른 글
스레드와 Yield (0) | 2024.11.18 |
---|---|
스레드 인터럽트 (0) | 2024.10.31 |
스레드 정보와 생명주기 (0) | 2024.10.29 |
API - SimpleDateFormat (날짜 형식으로 포맷) (0) | 2024.10.28 |
스레드 생성과 실행 - Runnable (0) | 2024.10.23 |