WEB/JAVA

내가 보려고 정리하는 JAVA 멀티 스레드 3- 스레드 상태

스레드는 실행대기 상태와 실행 상태를 번갈아가면서 자신의 run() 메서드를 조금씩 실행합니다.

그 후 더이상 실행할 코드가 없을 때 종료 상태가 됩니다.

 

스레드 객체 생성 -> start() -> 실행대기(스케줄링으로 인해) <-> 실행 -> 종료

 

- 스레드 스케줄링으로 선택된 스레드가 cpu를 점유하고 run() 메서드를 실행한다 (실행 상태)

- 스레드 스케줄링에 의해 다시 실행대기 상태로 돌아갈 수 있다.(실행대기 상태)

 

어떻게 제어할까?

 

1. 주어진 시간동안 일시 정지 sleep()

 

실행 중인 스레드를 일정 시간 멈출 수 있게 한다.

Thread 클래스의 정적 메서드인 sleep() 을 사용한다.

Thread.sleep(1000) // 1초 -> 밀리세컨드 (1/1000) 단위

 

* 주어진 시간이 되기전에 interrupt() 메서드가 호출되면 InterruptedException 발생! (예외 처리 필요)

 

2. 다른 스레드에게 실행 양보 yield()

 

Thread.yield();

이 메서드를 호출한 스레드는 실행 대기 상태로 돌아가고 동일한 우선순위 or 높은 우선순위를 갖는 다른 스레드가 실행 기회를 가질 수 있도록 해준다.

 

3. 다른 스레드에 종료 기다림 join()

 

스레드는 다른 스레드와 독립적으로 실행되어야 하는 것이 기본이지만 다른 스레드가 실행되어 종료될때 까지 기다리는 경우도 있다.

예를들어 다른 스레드의 계산값을 받아 이용하는 경우가 이에 해당한다. 

 

public static void main(String[] args){
	SumThread sumThread = new SumThread();
    sumThread.start();
    
    try{
    	sumThread.join():
	}cath(InterruptedException e){
	}
	}  
}

sumThread.join(); 에서 sumThread가 하는 일이 모두 종료될 때 까지 main 스레드를 일시정지 시킨다.

 

4. 스레드 간 협업 wait(), notify(), notifyAll()

 

두 개의 스레드를 번갈아가며 실행해야 할 경우가 있다.

방법은 공유객체에 있다 스레드가 작업할 내용을 각각 동기화 메서드로 구분해 놓고 한 스레드가 완료하면 notify() 메서드를 호출해서

일시 정지 상태에 있는 다른 스레드를 실행 대기 상태로 만들어 자신은 두번 작업하지 않도록 wait() 메서드를 호출하여 일시 정지 상태로 만든다.

 

5. 스레드의 안전한 종료 stop 플래그, interrept()

 

스레드는 자신의 run() 메서드가 모두 실행되면 자동적으로 종료된다. 

경우에 따라 강제 종료할 필요가 있다. stop() 메서드를 제공하고 있었지만 강제 종료하게 되면 사용중인 자원들이 불안정한 상태로 남겨지기 때문에 deprecated 되었다. 그렇다면 아래와 같은 방법을 사용하면 된다.

 

1. stop 플래그를 이용한다.

 

stop 플래그를 이용해서 run() 메서드의 종료를 유도하는 방법이다.

private boolean stop // stop 플래그 필드

public void run(){
	while(!stop){ // stop이 true가 되면 run()이 종료된다.
    	반복 실행되는 코드
		}
    // 자원 정리
	}
}

 

2. interrupt() 메서드를 이용한다.

 

스레드가 일시 정지 상태에 있을 때 InterruptedException 예외를 발생시키는 역할을 한다.

while문안에서 sleep() 메서드로 일시 정지를 시키게 되면 InterruptedExcetion이 발생하여 while문을 빠져나와 run() 메서드를 정상 종료한다.

thraed.interrupt()


//////////


while(true){
	if(Thread.interrupted()){
    	break;
       }
	}

-> a에서 thread.interrupt()를 사용하여 b가 멈추도록 한다.

b는 if문을 사용하여 interrupt()의 호출 여부를 확인하고 while문을 빠져나오면서 run() 메서드 종료