자바 쓰레드 스케쥴링 메소드-sleep(), interrupt(), suspend(), resume(), stop(), join(), yield()
자바 쓰레드 스케쥴링 메소드에 대해서 알아보자.
sleep()
sleep()은 지정된 시간동안 쓰레드를 멈추게 한다. 메소드 형식은 아래와 같다.
static void sleep(long millis), static void sleep(long millis, int nanos)
밀리세컨드와 나노세컨드의 시간단위로 세밀하게 값을 지정할 수 있지만, 어느 정도의 오차가 발생할 수 있다. 쓰레드가 0.0015초 동안 멈추게 하려면 sleep(1, 500000);로 주면 된다.
sleep()에 의해 일시정지 상태가 된 쓰레드는 지정된 시간이 다 되거나 interrupt()가 호출되면, InterruptedException이 발생되어 잠에서 깨어나 실행대기 상태가 된다. 그래서 sleep()을 호출할 때는 항상 try-catch문으로 예외를 처리해줘야 한다. sleep()은 항상 현재 실행중인 쓰레드에 대해서만 작동한다.
interrupt()
진행 중인 쓰레드의 작업이 끝나기 전에 취소시켜야할 때가 있다. 예를 들어 큰 파일을 다운로드 받을 때 시간이 너무 오래 걸리면 중간에 다운로드를 포기하고 취소할 수 있어야 한다. interrupt()는 쓰레드에게 작업을 멈추라고 요청을 하는데 쓰레드를 강제로 종료시키지는 못한다. 그저 쓰레드의 interrupted상태(인스턴스 변수)를 바꾸는 것일 뿐이다.
interrupted()는 쓰레드에 대해 interrupt()가 호출되었는지 알려준다. interrupt()가 호출되지 않았다면 false를, 호출되었다면 true를 반환한다.
isInterrupted()도 쓰레드의 interrupt()가 호출되었는지 확인하는데 사용할 수 있지만, interrupted()와 달리 쓰레드의 interrupted상태를 false로 초기화하지 않는다.
- void interrupt() : 쓰레드의 interrupted상태를 false에서 true로 변경
- boolean isInterrupted() : 쓰레드의 interrupted상태를 반환
- static boolean interrupted() : 현재 쓰레드의 interrupted 상태를 반환 후, false로 변경
ex)
해당 코드는 카운트다운 도중에 사용자의 입력이 들어오면 카운트 다운을 종료한다.
while문에서 i=0이 아니고 isInturrpted()가 false인 상태에서만 조건이 만족하므로, 중간에 메인쓰레드에서 값이 입력되어 interrupt()를 호출하면 true가 되어 while문이 종료되어 카운터가 종료된다.
ex)
위와 같이 카운트다운 출력과 입력을 같이하며, 값이 입력되면 카운트다운이 멈춘다.
suspend(), resume(), stop()
suspend()는 sleep()처럼 쓰레드를 멈추게 하고, suspend()에 의해 정지된 쓰레드는 resume()을 호출해야 다시 실행대기 상태가 된다. stop()은 호출되는 즉시 쓰레드가 종료된다. suspend()와 stop()은 교착상태(deadlock)을 일으키기 쉽게 작성되어 있으므로 사용이 권장 되지 않는다.
join(), yield()
join()은 쓰레드 자신이 하던 작업을 잠시 멈추고 다른 쓰레드가 지정된 시간동안 작업을 수행하도록 할 때 사용한다. 시간을 지정하지 않으면 해당 쓰레드가 작업을 모두 마칠 때 까지 기다리게 된다. 작업중에 다른 쓰레드의 작업이 먼저 수행되어야할 필요가 있을 때 사용한다. join()과 sleep()은 비슷하지만 join()은 특정 쓰레드에 동작하므로 static메소드가 아니다.
yield()는 쓰레드 자신에게 주어진 실행시간을 다음차례의 쓰레드에게 양보한다. 예를 들어 스케쥴러에 의해 1초의 실행시간을 할당받은 쓰레드가 0.5초의 시간동안 작업한 상태에서 yield()가 호출되면 나머지 0.5초는 포기하고 다시 실행대기 상태가 된다.