쓰레드에는 일반 쓰레드와 데몬 쓰레드가 있다. 데몬 쓰레드를 알아보자.
boolean isDaemon() : 쓰레드가 데몬 쓰레드인지 알려주는 역할을 한다.
데몬 쓰레드이면 true를 반환한다.
void setDaemon(boolean on) : 쓰레드를 데몬 쓰레드로 또는 사용자 쓰레드로 변경할때 사용한다. 매개변수를 true로 지정하면 데몬 쓰레드가 된다.
NEW : 쓰레드가 생성되고 아직 start()가 호출되지 않은 상태이다.
RUNNABLE : 실행 중 또는 실행 가능한 상태
BLOCKED : 동기화블럭에 의해서 일시정지된 상태이며 lock이 풀릴때까지 기다리는 상태이다.
WATING, TIMED_WATING : 쓰레드의 작업이 종료되지는 않았지만 실행가능하지 않은 일시정지상태이다. TIMED_WATINGd은 일시정지 시간이 지정된 경우를 의미한다.
TERMINATED : 쓰레드의 작업이 종료된 상태
현재 쓰레드를 지정된 시간동안 멈추게 한다. static 메서드라서 항상 현재 쓰레드에만 동작한다.
static void sleep(long millis) // 천분의 1초 단위
static void sleep(long millis, int nanos) // 천분의 1초 + 나노초
위와 같이 나노초까지 값을 지정할 수 있지만 어느정도 오차가 있다는것을 염두해 둬야 합니다.
sleep()에 의해서 일시정지 상태가 된 쓰레드는 지정된 시간이 다 되거나 interrupt()가 호출되면 잠에서 꺠어나 실행대기 상태가 됩니다.
sleep()를 호출할 때는 항상 try-catch문으로 예외를 처리해줘야 합니다. 그 이유는 InterruptedException이 발생하면 깨어나기 때문입니다.
InterruptedException은 Exception의 자손이기 때문에 항상 예외처리를 해줘야 합니다.
하지만 항상 예외처리를 해주는것이 어렵기 때문에 sleep()를 호출하고 예외처리가 된 메서드를 재정의해서 사용하는것도 좋은방법 입니다.
특정 쓰레드를 지정해서 멈추게 하는 것은 불가능하다. sleep() 메서드는 자기 자신한테 적용되는 메서드이다.
대기상태인 쓰레드를 실행대기 상태로 만든다.
void interrupt() : 쓰레드의 interrupted 상태를 false에서 true로 변경 해준다.
boolean isInterrupted() : 쓰레드의 interrupted 상태를 반환 해준다.
static boolean interrupted() : 현재 쓰레드의 interrupted 상태를 반환해주고 false로 초기화 해준다.
interrupted() 메서드는 static이기 때문에 현재 그 쓰레드의 상태를 반환해주고 false로 초기화 해주는것을 꼭 기억해야 합니다.
쓰레드의 실행을 일시정지 (suspend() ), 재개(resume()), 완전정지(stop()) 시키는 메서드 입니다.
void suspend() : 쓰레드를 일시정지 시킨다. 웨이팅 상태가 된다.
void resume() : suspend()에 의해 일시정지된 쓰레드를 실행대기 상태로 만든다.
void stop() : 쓰레드를 즉시 종료시킨다.
위의 세가지 메서드들을 이용하면 쓰레드를 제어하기 쉽다. 하지만 suspend(), stop()이 교착상태가 발생할 가능성이 있어서 권장되지 않는다. 현재 Java API 문서에서는 이 메서드들은 deprecated 되었다.
deprecated란?
전에는 사용되었지만, 앞으로 사용하지 않을 것을 권장한다는 뜻이다. 사용이 불가한것은 아니지만 이 메서드들을 deprecated 하였는데 Java 문법에서 삭제하지 않은 이유는 하위 호완성을 위해서 삭제하지 않은 것 뿐이다. 결론적으로 사용하지 않는 것이 좋다.
지정된 시간도안 특정 쓰레드가 작업하는 것을 기다린다.
void join() // 작업이 모두 끝날때까지
void join(long millis) // 천분의 1초 동안
void join(long mills, int nanos) // 천분의 1초 + 나노초 동안
사용할때 예외처리를 해줘야 한다. (InterruptedException이 발생하면 작업을 재개 합니다.)
sleep()와 유사하지만 다른점은 현재 쓰레드가 아닌 특정 쓰레드에서 동작하고 static 메서드가 아니라는 점이다.
남은 시간을 다음 쓰레드에게 양보하고, 자신(현재 쓰레드)는 실행대기 하는 메서드 입니다. static 메서드이다.
yield()와 interrupt()를 적절히 사용하면 응답성과 효율을 높일 수 있습니다.
yield()는 os스케줄러한테 알려주는것이기 때문에 반드시 동작한다는 보장이 없다.