011 Thread Join

강의 메모 - join() #

개요 #

  • join() 메서드는 한 스레드가 다른 스레드가 종료될 때까지 실행을 중지하고 대기상태에 들어갔다가 스레드가 종료되면 실행대기 상태로 전환된다
    • T1, T2가 있을때, T1이 T2의 모든 작업이 종료될때까지 대기했다가, T2의 작업이 다 끝나고나서 T1이 본인의 작업을 이어서 나가야할 경우
      • T1 기준으로 T2.join()을 수행
      • 대기는 T1이 하는것
  • 스레드의 순서를 제어하거나 다른 스레드의 작업을 기다려야 하거나 순차적인 흐름을 구성하고자 할 때 사용할 수 있다
  • Object 클래스의 wait() 네이티브 메서드로 연결되며 시스템 콜을 통해 커널모드로 수행한다. 내부적으로 wait() & notify() 흐름을 가지고 제어한다

API 및 예외처리 #

void join() throws InterruptedException #

  • 스레드의 작업이 종료 될 때까지 대기 상태를 유지한다

void join(long millis) throws InterruptedException #

  • 지정한 밀리초 시간 동안 스레드의 대기 상태를 유지한다
  • 밀리초에 대한 인수 값은 음수가 될 수 없으며 음수 일 경우 IllegalArgumentException 이 발생한다

void join( long millis, int nanos) InterruptedException #

  • 지정한 밀리초에 나노초를 더한 시간 동안 스레드의 대기 상태를 유지한다
  • 나노초의 범위는 0 에서 999999 이다

InterruptedException #

  • 스레드가 인터럽트 될 경우 InterruptedException 예외가 발생시킨다
  • 다른 스레드는 join() 을 수행 중인 스레드에게 인터럽트, 즉 중단(멈춤) 신호를 보낼 수 있다
  • InterruptedException 예외가 발생하면 스레드는 대기상태에서 실행대기 상태로 전환되어 실행상태를 기다린다
    • T1, T2가 있을때, T1이 T2의 모든 작업이 종료될때까지 대기했다가, T2의 작업이 다 끝나고나서 T1이 본인의 작업을 이어서 나가야할 경우
      • T1 기준으로 T2.join()을 수행
      • 대기는 T1이 하는것 -> T1에게 인터럽트를 거는 것
public static void main(String[] args) {
   Runnable r = new MyRunnable();
   Thread thread = new Thread(r);
   thread.start();
   try { // try-catch 문으로 예외 처리 해 주어야 한다
       thread.join(); // 메인 스레드는 thread 의 작업이 종료될 때 까지 일시정지한다
   } catch (InterruptedException e) {
       // 인터럽트 발생 시 예외 처리 필요
   }
}

join의 작동방식 #

  1. wait() & notify() img.png

  2. interrupt() 발생 img_1.png

join() 작동 방식 정리 #

  • join() 을 실행하면 OS 스케줄러는 현재 스레드를 대기 상태로 전환하고 join() 을 수행중인 스레드에게 CPU 를 사용하도록 한다
    • 현재 스레드는 대상 스레드.join() -> 현재 스레드가 대기로 빠지는 것임
  • join() 을 수행중인 스레드의 작업이 종료되면 현재 스레드는 실행 대기 상태로 전환 되고 CPU 가 실행을 재개할 때 까지 기다린다.
  • 실행 상태가 되면 스레드는 남은 지점부터 실행을 다시 시작한다
  • join() 을 수행중인 스레드가 여러 개일 경우 각 스레드의 작업이 종료될 때 까지 현재 스레드는 대기하고 종료 이후 실행을 재개하는 흐름을 반복한다
  • join() 을 수행중인 스레드에게 인터럽트가 발생할 경우 현재 스레드는 대기에서 해제되고 실행상태로 전환되어 예외를 처리하게 된다