- 스레드를 생성하고 시작하면 스레드는 다양한 상태를 가지게 된다. 스레드의 상태는 자동으로 변경될 수도 있고, 코드에 의해서 변경될 수도 있다.
- 스레드 객체를 생성하고 start() 메소드를 호출하면 바로 실행되는 것이 아니라 실행 대기 상태가 된다.
- 실행 대기 상태란 언제든지 실행할 준비가 되어 있는 상태를 의미한다.
- 실행 상태의 스레드는 run() 메소드를 모두 실행하기 전에 다시 실행 대기 상태로 돌아갈 수 있고, 실행 대기 상태에 있는 다른 스레드가 선택되어 실행 상태가 되기도 한다.
- 실행 상태에서 run() 메소드의 내용이 모두 실행되면 스레드의 실행이 멈추고 종료 상태가 된다.
스레드 상태
- 실행 상태(running) : 실행 대기 상태에 있는 스레드 중에서 운영체제는 하나의 스레드를 선택하고 CPU(코어)가 run()메소드를 실행하도록 한다. 이때를 실행 상태라고 한다.
- 종료(terminated) 상태 : 실행 상태에서 run() 메소드가 종료되면, 더 이상 실행할 코드가 없기 때문에 스레드의 실행이 멈추게 된 상태.
- 스레드는 실행 대기 상태와 실행 상태로 번갈아 변하면서, 경우에 따라 실행 상태에서 일시 정지 상태로 가기도 한다. 일시 정지 상태는 스레드가 실행할 수 없는 상태이다. 일시 정지 상태에서는 바로 실행 상태로 돌아갈 수 없고, 일시 정지 상태에서 빠져나와 실행 대기 상태로 가야 한다.
스레드 상태 제어
- 스레드 상태 제어 : 실행 중인 스레드의 상태를 변경하는 것
- 스레드 상태 제어는 주어진 시간 동안 일시 정지시키는 sleep() 메소드와 스레드를 안전하게 종료시키는 stop 플래그, interrupt()메소드를 사용한다.
- 아래의 그림에서 취소선으로 표시한 메소드는 스레드의 안전성을 해친다고 하여 더 이상 사용하지 않도록 권장된 Deprecated 메소드 이다.
메소드 | 설명 |
interrupt() | 일시 정지 상태의 스레드에서 InterruptedException을 발새시켜, 예외 처리 코드(catch)에서 실행 대기 상태로 가거나 종료 상태로 갈 수 있도록 한다. |
sleep(long millis) | 주어진 시간 동안 스레드를 일시 정지 상태로 만든다. 주어진 시간이 지나면 자동적으로 실행 대기 상태가 된다. |
stop() | 스레드를 즉시 종료한다. 불안전한 종료를 유발하므로 사용하지 않는 것이 좋다. |
notify(), notifyAll() | 동기화 블록 내에서 wait() 메소드에 의해 일시 정지 상태에 있는 스레드를 실행 대기 상태로 만든다. |
join() | join() 메서드를 호출한 스레드는 일시 정지 상태가 됩니다. 실행 대기 상태로 가려면 join() 메서드를 맴버로 가지는 스레드가 종료되거나, 매개값으로 주어진 시간이 지나야 합니다. |
wait() | 동기화(synchronized) 블록 내에서 스레드를 일시 정지 상태로 만듭니다. 매개값으로 주어진 시간이 지나면 자동적으로 실행 대기 상태로 됩니다. 시간이 주어지지 않으면 notify(), notifyAll() 메소드에 의해 실행 대기 상태로 갈 수 있습니다. |
주어진 시간 동안 일시 정지
- 실행 중인 스레드를 일정 시간 멈추게 하고 싶다면 Thread 클래스의 정적 메소드인 sleep()을 사용하면 된다. 다음과 같이 Thread.sleep() 메소드를 호출한 스레드는 주어진 시간 동안 일시 정지 상태가 되고, 다시 실행 대기 상태로 돌아간다.
안전한 종료
- Thread는 스레드를 즉시 종료하기 위해서 stop()메소드를 제공하고 있는데, 이 메소드는 deprecated(중요도가 떨어져 이제 사용되지 않음)되었다.
- 그 이유는 stop()메소드로 스레드를 갑자기 종료하면 스레드가 사용 중이던 자원들이 불안전한 상태로 남겨지기 때문이다.
- 스레드를 안전하게 종료하기 위해서 stop플래그를 이용하거나 interrupt() 메소드를 이용하는 방법이 있다.
stop 플래그를 이용하는 방법
스레드는 run() 메소드가 끝나면 자동적으로 종료되므로, run() 메소드가 정상적으로 종료되도록 유도하는 것이다. 다음 코드는 stop 풀래그를 이용해서 run() 메소드의 종료를 유도한다.
public class XXXThread extends Thread{
private boolean stop; // stop 플래그
public void run(){
while(!stop){
// 스레드가 반복 실행하는 코드;
}
// 스레드가 사용한 자원 정리
}
}
위 코드에서 stop 필드가 false일 경우에는 while문의 조건식이 true가 되어 반복 실행하지만, stop 필드가 true일 경우에는 while문의 조건식이 false가 되어 while문을 빠져나온다. 그리고 스레드가 사용한 자원을 정리하고, run() 메소드가 끝나게 됨으로써 스레드는 안전하게 종료된다.
데몬 스레드
- 주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드
- 주 스레드가 종료되면 데몬 스레드는 강제적으로 자동 종료 되는데, 주 스레드의 보조 역할을 수행하므로 주 스레드가 종료되면 데몬 스레드의 존재 의미가 사라지기 때문이다.
[ 참고자료 ]
- <혼자 공부하는 자바> 신용권 지음
- https://velog.io/@sa1341/%EB%A9%80%ED%8B%B0-%EC%8A%A4%EB%A0%88%EB%93%9C%EC%9D%98-%EC%83%81%ED%83%9C-%EC%A0%9C%EC%96%B4
'Coding > Java' 카테고리의 다른 글
[31] JAVA LIFO와 FIFO 컬렉션 (0) | 2022.12.25 |
---|---|
[30] JAVA 컬렉션 프레임워크 (0) | 2022.12.25 |
[28] JAVA 멀티스레드 (0) | 2022.12.21 |
[27] JAVA 기초 복습 (0) | 2022.12.14 |
[26] JAVA 익명 객체 (Anonymous) (0) | 2022.12.10 |