Inflearn brand logo image

인프런 커뮤니티 질문&답변

창신동 장첸님의 프로필 이미지
창신동 장첸

작성한 질문수

김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성

Join 실습 질문

작성

·

130

·

수정됨

0

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();

        // 스레드가 종료될 때 까지 대기
        log("join() - main 스레드 대기 시작");
        thread1.join();
        thread2.join();
        log("main 스레드 대기 완료");

        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("작업 시작");
            sleep(2000);
            int sum = 0;
            for (int i = startValue; i <= endValue; i++) {
                sum += i;
            }
            result = sum;
            log("작업 완료 result = " + result);
        }
    }
}

안녕하세요.

위 코드는 강의실습에 사용된 코드입니다.

개인적으로 thread1.join(), thread2.join() 에 대해 main쓰레드가 WAITING 상태인지를 확인하고 싶어

아래와 같이 코드 중간 중간에 상태를 체크해봤습니다.

        log("main 쓰레드 상태: " + Thread.currentThread().getState());
        thread1.join();
        log("main 쓰레드 상태: " + Thread.currentThread().getState());
        thread2.join();
        log("main 쓰레드 상태: " + Thread.currentThread().getState());

결과는 모두 RUNNABLE로 나타나는데요.

sleep시간을 늘려봐도 여전히 RUNNABLE상태가 나옵니다.

코드의 어떤 부분을 수정해야지 WAITING상태를 확인할 수 있는지 궁금합니다~!

 

답변 2

1

메인 스레드가 RUNNABLE 상태에서만 log()를 실행할 수 있으므로 항상 RUNNABLE이 출력됩니다.

생각하는자 님이 적어주신 코드처럼 상태를 조회하는 스레드와 log를 출력하는 스레드를 분리하면 WAITING을 확인할 수 있습니다.

제가 실행한 코드는 다음과 같습니다. 길이를 줄이기 위해 SumTask의 계산 부분을 제거하고 Task 생성 부분은 인라인으로 넣었습니다.

package thread.control.test;

import static util.MyLogger.log;
import static util.ThreadUtils.sleep;

public class JoinMainV3 {

	public static void main(String[] args) {
		Thread mainTask = new Thread(new MainTask(), "MainTask");
		mainTask.start();
		log("MainTask 스레드 상태: " + mainTask.getState());
		sleep(1000);
		log("MainTask 스레드 상태: " + mainTask.getState());
		sleep(1500);
		log("MainTask 스레드 상태: " + mainTask.getState());
	}

	static class MainTask implements Runnable {

		@Override
		public void run() {
			log("Start");
			Thread thread1 = new Thread(new Task(), "thread-1");
			Thread thread2 = new Thread(new Task(), "thread-2");

			thread1.start();
			thread2.start();

			log("join() - MainTask 스레드 대기 시작");
			try {
				thread1.join();
				thread2.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			log("MainTask 스레드 대기 완료");
			log("End");
		}

	}

	static class Task implements Runnable {
		@Override
		public void run() {
			log("작업 시작");
			sleep(2000);
			log("작업 완료");
		}
	}
}

로그 결과는 다음과 같습니다. 두 번째 조회 시 WAITING 상태가 나오는 것을 확인할 수 있습니다.

11:02:29.123 [ main] MainTask 스레드 상태: RUNNABLE 
11:02:29.124 [ MainTask] Start 
11:02:29.143 [ MainTask] join() - MainTask 스레드 대기 시작 
11:02:29.146 [ thread-1] 작업 시작 
11:02:29.147 [ thread-2] 작업 시작 
11:02:30.149 [ main] MainTask 스레드 상태: WAITING 
11:02:31.155 [ thread-2] 작업 완료 
11:02:31.155 [ thread-1] 작업 완료 
11:02:31.156 [ MainTask] MainTask 스레드 대기 완료 
11:02:31.157 [ MainTask] End 
11:02:31.663 [ main] MainTask 스레드 상태: TERMINATED

0

메인 내용을 run()에 집어넣고 main에 새로운 스레드 를 만들어서 하면 wating상태가 나오긴 합니다

image.png

아직 배운지는 모르겠지만. ThreadStateMain 클래스 를 참조해서 만들었습니다.

창신동 장첸님의 프로필 이미지
창신동 장첸

작성한 질문수

질문하기