Continuous Challenge

[이것이 자바다] 스레드 상태 본문

Study/이것이 자바다

[이것이 자바다] 스레드 상태

응굥 2023. 5. 2. 18:22
728x90
728x90

스레드 상태

1. 스레드 객체를 생성(NEW)하고, start() 메소드를 호출하면 실행 대기 상태(RUNNABLE)가 된다.

2. 실행을 대기하는 스레드는 CPU 스케쥴링에 따라 CPU를 점유하고 run() 메소드를 실행한다. 이 때를 실행(RUNNING) 상태라고 한다.

3. 실행 스레드는 run() 메소드를 모두 실행하기 전에 스케줄링에 의해 다시 실행 대기 상태로 돌아갈 수 있다.
   이렇게 스레드는 실행 대기 상태와 실행 상태를 번갈아 가면서 자신의 run() 메소드를 조금씩 실행한다.

4. 실행 상태에서 run() 메소드가 종료되면 더 이상 실행할 코드가 없기 때문에 스레드의 실행은 멈추게 된다. 이를 종료 상태(TERMINATED)라고 한다.

 

실행 상태에서 일시 정지 상태로 가기도 하는데, 일시 정지 상태는 스레드가 실행할 수 없는 상태를 말한다.

스레드가 다시 실행 상태로 가기 위해서는 일시 정지 상태에서 실행 대기 상태로 가야 한다.

 

일시 정지로 보냄

  • sleep(long millis) : 주어진 시간 동안 스레드를 일시 정지 상태로 만든다. 주어진 시간이 지나면 자동적으로 실행 대기 상태가 된다.
  • join() : join() 메소드를 호출한 스레드는 일시 정지 상태가 된다. 실행 대기 상태가 되려면 join() 메소드를 가진 스레드가 종료되어야 한다.
  • wait() : 동기화 블록 내에서 스레드를 일시 정지 상태로 만든다.

일시 정지에서 벗어남

  • interrupt() : 일시 정지 상태일 경우, InterruptedException을 발생시켜 실행 대기 상태 또는 종료 상태로 만든다.
  • notify(), notifyAll() : wait() 메소드로 인해 일시 정지 상태인 스레드를 실행 대기 상태로 만든다.

실행 대기로 보냄

  • yield() : 실행 상태에서 다른 스레드에게 실행을 양보하고 실행 대기 상태가 된다.

 

다른 스레드의 종료를 기다리는 경우

스레드는 다른 스레드와 독립적으로 실행하지만 다른 스레드가 종료될 때까지 기다렸다가 실행을 해야 하는 경우도 있다.

이를 위해 스레드는 join() 메소드를 제공한다. 위 그림에서 ThreadA가 ThreadB의 join() 메소드를 호출하면 ThreadA는 ThreadB가 종료할 때까지 일시 정지 상태가 된다. ThreadB의 run() 메소드가 종료되고 나서야 비로소 ThreadA는 일시 정지에서 풀려 다음 코드를 실행한다. 

 

다른 스레드에게 실행을 양보하는 경우

스레드가 처리하는 작업은 반복적인 실행을 위해 for 문이나 while 문을 포함하는 경우가 많은데, 가끔 반복문이 무의미한 작업을 하는 경우가 있다.

public void run() {
	while(true) {
		if(work) {
        	System.out.println("ThreadA 작업 내용");
        }
    }
}

위 코드를 보면 work의 값이 false일 경우 while 문은 어떠한 실행문도 실행하지 않고 무의미한 반복을 한다.

이 때는 다른 스레드에게 실행을 양보하고 자신은 실행 대기 상태로 가는 것이 프로그램 성능에 도움이 된다. 이런 기능을 위해 Thread는 yield() 메소드를 제공한다. yield() 를 호출한 스레드는 실행 대기 상태로 돌아가고, 다른 스레드가 실행 상태가 된다.

 

public void run() {
	while(true) {
    	if(work) {
        	System.out.println("ThreadA 작업 내용");
        } else {
        	Thread.yield();
        }
    }
}

 

위 코드는 무의미한 반복을 하지 않고 다른 스레드에게 실행을 양보하도록 코드를 수정한 것이다.

 

728x90
728x90
Comments