🙈

⃝ 동글동글 ⃝

🪐ᐩ˖ 🍎

Java/기초

[Java 기초] Thread(스레드) 실행제어

JONG_UK 2023. 6. 16. 23:54
728x90
반응형
SMALL

효율적인 멀티스레드 프로그래밍을 위해서는 정교한 스케줄링을 통해 프로세스에게 주어진 자원과 시간을 여러 스레드가 낭비 없이 잘 사용하도록 해야 한다.

스레드 상태

 

스레드의 생성과 소멸 과정

출처 : https://joont92.github.io/java/%EC%93%B0%EB%A0%88%EB%93%9C-%EA%B8%B0%EB%B3%B8/

  1. 스레드를 생성하고 start()를 호출하면 바로 실행되는 것이 아니라 실행대기열에 저장되어 자신의 차례가 될 때까지 기다리고, 실행대기열은 Queue와 같은 구조로 먼저 실행대기열에 들어온 스레드부터 실행한다.
  2. 실행대기상태에 있다가 자신의 차례가 되면 실행상태가 된다.
  3. 주어진 실행시간이 다되거나 yield()를 만나면 다시 실행대기상태가 되고 다음 차례의 스레드가 실행상태가 된다.
  4. 실행 중에 suspend(), sleep(), wait(), join(), I/O block에 의해 일시정지 상태가 될 수 있다.
  5. 지정된 일시정지시간이 다되거나(time-out), notify(), resume(), interrupt()가 호출되면 일시정지상태를 벗어나 다시 실행대기열에 저장되어 자신의 차례를 기다린다.
  6. 실행을 모두 마치거나 stop()이 호출되면 스레드는 소멸한다.

 

스레드 스케줄링 메서드

 

sleep(long millis)

- 일정시간 동안 스레드를 멈추게 한다.

static void sleep(long millis) 		   // -> 1/1000 초 단위
static void sleep(long millis, int nanos) // -> 1/1000 초 단위 + 나노초

// Example
try {
	Thread.sleep(1, 500000); // 쓰레드를 0.0015초 동안 멈춤
} catch(InterruptedException e) { ... } // 예외처리를 해주어야 프로그램이 멈추지 않는다.

sleep()에 의해 일시정지 상태가 된 스레드는 지정된 시간이 다 되거나 interrupt()가 호출되면(InterruptedException 발생), 잠에서 깨어나 실행대기 상태가 된다.

 

interrupt()와 interrupted()

- 쓰레드의 작업을 취소한다.

- 대기(Waiting) 상태인 스레드를 실행대기(Runnable) 상태로 만든다.

 

진행 중인 스레드의 작업이 끝나기 전에 취소시켜야 할 때가 있다. 그때 interrupt() 메서드를 이용하여 스레드에게 작업을 멈추라고 요청한다. 하지만 단지 멈추라고 요청만 하는 것일 뿐 스레드를 강제로 종료시키지 못한다.

interrupt() 메서드는 그저 스레드의 interrupted 상태(인스턴스 변수)를 바꾸는 것일 뿐이다.

 

interrupted() 메서드는 인스턴스 변수의 값을 읽어와 리턴하는 변수다.

Thread th = new Thread();
th.start();

th.interrupt();

class MyThread extends Thread {
	public void run() {
    	while(!interrupted()) {
        	...
        }
    }
}
// Thread 클래스 interrupted 관련 예시
class Thread {
    boolean interrupted = false; // 인스턴스 변수
    ...
    boolean isInterrupted() {
    	return interrupted;
    }
    boolean interrupt() {
    	interrupted = true;
    }
}

 

suspend(), resume(), stop()

- suspend() 메서드는 sleep()처럼 스레드를 멈추게 한다.

- suspend() 메서드를 통해 멈춘 쓰레드는 resume() 메서드를 이용해 다시 실행대기 상태로 만들 수 있다.

- stop() 메서드로 호출하면 즉시 쓰레드가 종료된다.

 

하지만 suspend()와 stop() 메서드는 교착상태(Deadlock)를 만들 우려가 있어 사용에 권장되지 않는다.(현재 Deprecated 상태)

 

yield()

- 자신의 실행시간의 남은 시간을 다음 쓰레드에게 양보하고, 자신(현재 스레드)은 실행대기한다.

- yield()와 interrupt()를 적절히 사용하면, 응답성과 효율을 높일 수 있다.

예시 사진을 보면 suspend() 메서드를 이용해 스레드에 신호를 주어 실행대기 상태의 스레드를 다시 수행할 수 있게 한다. 

 

join()

- 지정된 시간동안 특정 스레드가 작업하는 것을 기다린다.

- 예외처리를 해야 한다. InterruptedException 예외가 발생하면 작업을 다시 시작한다.

 

스레드 자신이 하던 작업을 잠시 멈추고 다른 스레드가 지정된 시간 동안 작업을 수행하도록 할 때 join()을 사용한다.

join() 또한 sleep()처럼 interrupt()에 의해 대기 상태에서 벗어날 수 있다.

728x90
반응형
LIST