Inflearn brand logo image

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

양성빈(Robert)님의 프로필 이미지
양성빈(Robert)

작성한 질문수

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

문제와 풀이

문제와 풀이2번 궁금증

해결된 질문

작성

·

133

1

영한님 안녕하세요. 문제와 풀이 2번을 풀고 고민하고 강의를 학습해도 약간의 의문점이 생겨서 질문드립니다.

 

Thread t1 = new Thread(new MyTask(), "t1");
        Thread t2 = new Thread(new MyTask(), "t2");
        Thread t3 = new Thread(new MyTask(), "t3");

        t1.start();
        t2.start();
        t3.start();
        // 1초

        t1.join();
        t2.join();
        t3.join();
        // 대기

현재 위와 같은 코드에서 main 쓰레드가 t1, t2, t3에게 작업을 시킵니다. 그리고 t1의 join을 만나니까 t1이 작업이 완전히 끝날때까지 대기상태에 빠집니다. 그리고 t1이 작업이 완료되면 t2.join()이 실행된다면 결과가 아래와 같이 나와야 하는데 왜 이렇게 안 되는지 의문입니다. ㅠㅠ

t1: 1

t1: 2

t1: 3

t2: 1

t2: 2

t2: 3

...

답변 2

1

  1. t1.join()main()에서 호출했습니다.

  2. t1.join()t1run() 메서드에서 정의한 모든 코드가 수행될 때까지 t1.join() 다음에 있는 코드를 수행하지 않도록 합니다.

  3. 따라서 main()에서 t1.join() 이전에 있는 t1.start(), t2.start(), t3.start()t1의 모든 코드가 실행되었는지 여부에 구애받지 않고 모두 정상적으로 작동합니다.

  4. t1 스레드를 비롯하여 모든 t 스레드는 로그를 출력 후 1초간 대기합니다.

  5. 1초라는 시간은 다른 t2, t3 스레드가 한 줄의 로그를 출력하는 데에는 충분한 시간입니다. 따라서 t1이 1초 대기하는 동안 t2, t3도 각자 로그를 출력하고 1초를 대기합니다. 그러면 또 t2, t3가 대기하는 시간동안 t1의 1초 대기가 끝나고 다음 로그를 출력하고, ...
    따라서 다음과 같은 출력 결과를 얻습니다.

    16:58:43.144 [       t1] 1
    16:58:43.144 [       t2] 1
    16:58:43.144 [       t3] 1
    16:58:44.152 [       t1] 2
    16:58:44.152 [       t2] 2
    16:58:44.152 [       t3] 2
    16:58:45.154 [       t1] 3
    16:58:45.154 [       t2] 3
    16:58:45.154 [       t3] 3
    모든 스레드 실행 완료. 수행 시간: 3초
    
    Process finished with exit code 0

친절한 답변 감사드립니다. 설명을 읽어보니 이해가 되었습니다!

0

안녕하세요, 인프런 AI 인턴입니다. 양성빈님.

귀하의 질문은 자바에서 스레드 동작 및 join() 메소드의 역할에 대한 것으로 보입니다. join()을 사용하여 스레드의 순차적인 실행을 기대하셨는데, 예상과 다른 결과가 나오는 이유에 대한 설명을 드리겠습니다.

  1. join() 메소드의 역할: join() 메소드는 호출된 스레드가 작업을 마칠 때까지 기다리게 합니다. 즉, t1.join()은 메인 스레드가 t1 스레드가 완료될 때까지 대기하게 만들고, 그 후에 t2.join(), t3.join() 순서로 진행됩니다.

  2. 스레드의 동시성: 스레드가 시작(start())될 때, 각 스레드는 독립적으로 실행되며, 각 스레드의 실행 순서는 JVM 스케줄러와 오퍼레이팅 시스템의 스케줄러에 의해 결정됩니다. 따라서 t1.join() 전에 t2t3가 이미 동시에 실행되고 있을 수 있습니다. 이로 인해 생각하신 것처럼 t1: 1, t1: 2, ..., t2: 1, ...의 순차적인 출력이 보장되지 않습니다.

  3. 실행 중인 스레드: join() 메소드는 색인된 스레드에서 start() 호출 이후 실행 중인 작업이 완료될 때까지 대기하는 것이므로, 이미 작업이 실행 중일 경우에는 그 진행을 중단하지 않습니다.

추가적으로, 관련 질문에서 유사한 상황에 대한 상세한 설명이 담긴 김영한 강사님의 답변 링크를 참고하시면 더 깊이 있는 이해를 얻으실 수 있습니다. 해당 포럼에는 join() 메소드의 사용법과 스레드 동작에 대해 설명하는 답변이 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

말씀한것처럼 t1, t2, t3가 동시에 실행이 된다고 하면, t1.join을 만나니까 t1의 작업이 완료될때까지 main 쓰레드는 대기를 해야하고 그 동안 t2, t3가 개별로 1, 2, 3을 찍을것 같은데 즉 아래와 같이 출력이 나온다고 예상이 되는데 왜 1, 1, 1 -> 2,2,2 -> 3,3,3이 나오는지 궁금합니다.

t1: 1

t1: 2

t2: 1

t3: 1

t1: 3

t2: 2

t3: 2

t2: 3

t3: 3

모든 스레드 실행 완료

 

for문 안에 sleep(1000); 때문에 그런듯합니다

재현님 답변 감사드립니다!

양성빈(Robert)님의 프로필 이미지
양성빈(Robert)

작성한 질문수

질문하기