009 Thread Status

강의 메모 - 스레드 생명주기와 상태 #

개요 #

  • 자바 스레드는 생성, 실행, 종료에 따른 상태를 가지고있다. OS 스레드 상태를 의미하지 않는다.
  • 자바 스레드는 어떤 시점이던 6가지 상태 중 오직 1개의 상태를 가질 수 있다.
  • 자바 스레드의 현재 상태를 가져오려면 Thread의 getState() 메서드를 사용하여 가져올 수 있다.
  • Thread 클래스에는 스레드 상태에 대한 ENUM 상수를 정의하는 Thread.State 클래스를 제공한다.

스레드 상태 #

img.png

  • NEW : 객체만 생성된 상태
  • RUNNABLE
  • WAITING : 대기는 언제하는가? 대표적으로 쓰레드가 CPU에서 할당받아서 실행하다가, I/O 입출력 관련 작업이 발생되어 CPU를 사용하지 않는 대기 상태
  • TIMED_WAITING : 대기 시간이 지정된 상태
  • BLOCKED : 락(lock) : 쓰레드가 여러개일때 공유 데이터 접근시 여러 문제가 발생하는데, 동시에 접근하지 못하도록 막는것
  • TERMINATED

스레드 생명주기 #

img_1.png

Running 상태 - 스레드에는 없는 상태정보, 전체 생명주기 흐름을 이해하기 위해 실행중인 상태로 표시한것일 뿐, Runnable 상태에 해당한다.

  1. 객체 생성 상태 스레드 객체는 생성되었지만 아직 start() 하지 않은 상태 JVM에는 객체가 존재하지만 아직 커널로의 실행은 안된 상태

  2. Runnable start()를 실행하면 내부적으로 커널로의 실행이 일어나고 커널 스레드로 1:1 매핑된다. 스레드는 바로 실행 상태가 아닌 언제든지 실행할 준비가 되어있는 실행 가능한 상태가 된다. 스레드가 실행 상태로 전환하기 위해서는 현재 스레드가 어떤 상태로 존재하든지, 반드시 실행 대기 상태를 거쳐야한다.

  3. 스케줄링 실행 가능한 상태의 스레드에게 실행할 시간을 제공하는 것은 OS 스케줄러의 책임이다 스케줄러는 멀티 스레드 환경에서 각 스레드에게 고정된 시간을 할당해서 실행 상태와 실행 가능한 상태를 오가도록 스케줄링한다 (스레드가 여러개있을때 스레드마다 번갈아가면서 CPU 할당 시간을 고정해서 그만큼 수행한다)

  4. 실행상태 스레드는 스케줄러에 의해 스케줄링이 되면 실행 상태로 전환되고, CPU를 할당받아 run() 메서드를 실행한다. 스레드는 아주 짧은 시간동안 실행된 다음 스레드가 실행될 수 있도록 CPU를 일시 중지하고 다른 스레드에 양도하게된다 (컨텍스트 스위칭) 실행 상태에서 생성과 종료 상태를 제외한 다른 상태로 전환될 때 스레드 혹은 프로세스간 컨텍스트 스위칭이 일어난다고 할 수 있다.

  5. 실행상태 -> 실행 대기 상태 실행 상태에서 스레드의 yield() 메서드를 호출하거나 운영체제 스케줄러에 의해 CPU 실행을 일시 중지하는 경우 실행 가능한 상태로 전환한다.

  6. 실행 상태로 전환

  7. 일시 정지 상태 (지정된 시간이 있는 경우 - Timed Waiting) 스레드는 sleep 및 time-out 매개변수가 있는 메서드를 호출할때 시간이 지정된 대기 상태가 된다 스레드의 대기 시간이 길어지고 CPU의 할당을 계속 받지 못하는 상황이 발생하면 기아 상태가 발생하게 되는데 이 상황을 피할 수 있다.

  8. 실행 대기 상태 스레드가 대기 상태의 지정 시간이 완료되거나 다른 스레드에 의해 인터럽트가 발생하거나 대기가 해제되도록 통지를 받게되면 실행 대기 상태가 된다.

  9. 임계 영역 동시적 접근 멀티 스레드 환경에서 각 스레드가 동기화된 임계 영역에 접근을 시도 (Critical Section 접근 시도 : 임계영역; 오직 하나의 쓰레드가 접근할 수 있도록 처리된 영역)

  10. 일시 정지 상태 (차단됨 - Blocked) 스레드가 동기화된 임계 영역에 접근을 시도하다가 Lock을 획득하지 못해서 차단된 상태 스레드는 Lock을 획득할 때까지 대기한다.

  11. 일시 정지 상태 -> 실행 대기 상태 스레드가 Lock을 획득하게 되면 실행 대기 상태가 된다.

  12. 실행 상태로 전환 실행 대기상태에서 가능

  13. 일시 정지 상태 (Waiting 상태) 스레드가 실행 상태에서 다른 스레드가 특정 작업을 수행하기를 기다리는 상태 (자기 스스로 빠져나오지못함) wait()은 다른 스레드에 의해 notify() 받을때까지, join()은 스레드의 실행이 종료되거나 인터럽트가 발생할때까지 대기한다. joing() : 쓰레드A, 쓰레드B가 있을때 쓰레드 A에서 B.joing() 실행하면 쓰레드B의 모든 작업(run 메서드 내부) 이 모두 완료될때까지 대기하는것

  14. 일시 정지 상태 -> 실행 대기 상태 wait 상태의 쓰레드가 다른 쓰레드에 의해 notify() 혹은 notifyAll()이 일어나면 실행 대기 상태가 된다 다른 스레드에 의해 인터럽트가 발생할 경우 실행 대기 상태로 전환한다

  15. 실행 상태로 전환

  16. 실행 종료 상태 실행이 완료되었거나 오류 또는 처리되지않은 예외와 같이 비정상적으로 종료된 상태 종료된 스레드는 종료되어 더이상 사용할 수 없다

정리 #

img_2.png

스레드 생명주기와 상태를 잘 알아야, 스레드를 효과적으로 잘 운용할 수 있다.

  • 스레드는 어떤 상황, 시점, 조건에 의해 상태 전이가 일어나는가?
  • 스레드의 API를 사용함에 있어 해당 API가 어떤 상태를 일으키며 스레드간 영향을 미치게 되는가? 스레드의 실행 관점에서 보면 출발지가 스레드의 start() 메서드 실행이라면 목적지는 스레드의 run() 메서드 실행이 된다는 점이다.