728x90

스레드의 상태
- New (새로운 상태): 스레드가 생성되었으나 아직 시작되지 않은 상태.
- Runnable (실행 가능 상태): 스레드가 실행 중이거나 실행될 준비가 된 상태.
- 일시 중지 상태들 (Suspended States)
- Blocked (차단 상태): 스레드가 동기화 락을 기다리는 상태.
- Waiting (대기 상태): 스레드가 무기한으로 다른 스레드의 작업을 기다리는 상태.
- Timed Waiting (시간제한 대기 상태): 스레드가 일정 시간 동안 다른 스레드의 작업을 기다리는 상태.
- Terminated (종료 상태): 스레드의 실행이 완료된 상태.
참고: 자바에서 스레드의 일시 중지 상태들(Suspended States)이라는 상태는 없다. 스레드가 기다리는 상태들
을 묶어서 쉽게 설명하기 위해 사용한 용어이다.
자바 스레드의 생명 주기
New (새로운 상태)
- 스레드가 생성되고 아직 시작되지 않은 상태이다.
- 이 상태에서는 "Thread" 객체가 생성되지만, "start()" 메서드가 호출되지 않은 상태이다.
- 예: "Thread thread = new Thread(runnable);"
Runnable (실행 가능 상태)
- 스레드가 실행될 준비가 된 상태이다. 이 상태에서 스레드는 실제로 CPU에서 실행될 수 있다.
- "start()" 메서드가 호출되면 스레드는 이 상태로 들어간다.
- 예: `thread.start();`
- 이 상태는 스레드가 실행될 준비가 되어 있음을 나타내며, 실제로 CPU에서 실행될 수 있는 상태이다. 그러나 Runnable 상태에 있는 모든 스레드가 동시에 실행되는 것은 아니다. 운영체제의 스케줄러가 각 스레드 에 CPU 시간을 할당하여 실행하기 때문에, Runnable 상태에 있는 스레드는 스케줄러의 실행 대기열에 포 함되어 있다가 차례로 CPU에서 실행된다.
- 참고로 운영체제 스케줄러의 실행 대기열에 있든, CPU에서 실제 실행되고 있든 모두 `RUNNABLE 상태이다. 자바에서 둘을 구분해서 확인할 수는 없다.
- 보통 실행 상태라고 부른다.
Blocked (차단 상태)
- 스레드가 다른 스레드에 의해 동기화 락을 얻기 위해 기다리는 상태이다.
- 예를 들어, "synchronized" 블록에 진입하기 위해 락을 얻어야 하는 경우 이 상태에 들어간다.
- 예: "synchronized (lock) { ... }" 코드 블록에 진입하려고 할 때, 다른 스레드가 이미 "lock" 의 락을 가지고 있는 경우.
Waiting (대기 상태)
- 스레드가 다른 스레드의 특정 작업이 완료되기를 무기한 기다리는 상태이다.
- wait() , join() 메서드가 호출될 때 이 상태가 된다.
- 스레드는 다른 스레드가 "notify()" 또는 "notifyAll()" 메서드를 호출하거나, "join()"이 완료될 때까지 기다린다.
- 예: `object.wait();
Timed Waiting (시간제한 대기 상태)
- 스레드가 특정 시간 동안 다른 스레드의 작업이 완료되기를 기다리는 상태이다.
- sleep(long millis) , wait(long timeout) , join(long millis) 메서드가 호출될 때 이 상태가 된다.
- 주어진 시간이 경과하거나 다른 스레드가 해당 스레드를 깨우면 이 상태에서 벗어난다.
- 예: Thread.sleep(1000);
Terminated (종료 상태)
- 스레드의 실행이 완료된 상태이다.
- 스레드가 정상적으로 종료되거나, 예외가 발생하여 종료된 경우 이 상태로 들어간다.
- 스레드는 한 번 종료되면 다시 시작할 수 없다.
자바 스레드의 상태 전이 과정
- New → Runnable: "start()" 메서드를 호출하면 스레드가 "Runnable" 상태로 전이된다.
- Runnable → Blocked/Waiting/Timed Waiting: 스레드가 락을 얻지 못하거나, "wait()" 또는 "sleep()" 메서드를 호출할 때 해당 상태로 전이된다.
- Blocked/Waiting/Timed Waiting → Runnable: 스레드가 락을 얻거나, 기다림이 완료되면 다시 "Runnable" 상태로 돌아간다.
- Runnable → Terminated: 스레드의 "run()" 메서드가 완료되면 스레드는 "Terminated" 상태가 된다.
코드로 살펴보기


- Thread.currentThread()를 호출하면 해당 코드를 실행하는 스레드 객체를 조회할 수 있다.
- Thread.sleep() : 해당 코드를 호출한 스레드는 "TIMED_WAITING" 상태가 되면서 특정 시간 만큼 대기한다. 시간은 밀리초(ms) 단위이다. 1밀리초 = 1/1000 초, 1000밀리초 = 1초이다.
- Thread.sleep()은 "InterruptedException" 이라는 체크 예외를 던진다. 따라서 체크 예외를 잡아서 처리하거나 던져야 한다.
- run() 메서드 안에서는 체크 예외를 반드시 잡아야 한다. "InterruptedException" 은 인터럽트가 걸릴 때 발생한다.

- state1 = NEW
- "main" 스레드를 통해 "myThread" 객체를 생성한다. 스레드 객체만 생성하고 아직 start()를 호출하지 않았기 때문에 "NEW" 상태이다.
- state2 = RUNNABLE
- myThread.start()를 호출해서 "myThread"를 실행 상태로 만든다. 따라서 "RUNNABLE" 상태가 된다.
- 참고로 실행 상태가 너무 빨리 지나가기 때문에 "main" 스레드에서 "myThread"의 상태를 확인하기는 어렵다. 대신에 자기 자신인 "myThread"에서 실행 중인 자신의 상태를 확인했다.
- state3 = TIMED_WAITING
- Thread.sleep(3000) : 해당 코드를 호출한 스레드는 3000ms (3초)간 대기한다. "myThread"가 해당 코드를 호출했으므로 3초간 대기하면서 "TIMED_WAITING" 상태로 변한다.
- 참고로 이때 "main" 스레드가 "myThread" 의 "TIMED_WAITING" 상태를 확인하기 위해 1초간 대기하고 상태를 확인했다.
- state4 = RUNNABLE
- "myThread" 는 3초의 시간 대기 후 "TIMED_WAITING" 상태에서 빠져나와 다시 실행될 수 있는 "RUNNABLE" 상태로 바뀐다.
- state5 = TERMINATED
- "myThread"가 run() 메서드를 실행 종료하고 나면 "TERMINATED" 상태가 된다.
- "myThread" 입장에서 run()이 스택에 남은 마지막 메서드인데, run()까지 실행되고 나면 스택이 완전히 비워진다. 이렇게 스택이 비워지면 해당 스택을 사용하는 스레드도 종료된다.
728x90
'멀티스레드와 동시성' 카테고리의 다른 글
| Ch03. 스레드 제어와 생명 주기 - Join (0) | 2024.08.04 |
|---|---|
| Ch03. 스레드 제어와 생명 주기 - 체크 예외 재정의 (0) | 2024.08.02 |
| Ch03. 스레드 제어와 생명 주기 - 스레드 기본 정보 (0) | 2024.08.02 |
| Ch02. 스레드 생성과 실행 -Runnable을 만드는 다양한 방법 (0) | 2024.08.01 |
| Ch02. 스레드 생성과 실행 - 여러 스레드 만들기 (0) | 2024.08.01 |