크게 보면 주요한 것은 RUNNABLE 과 UNRUNNABLE 로 나뉜다고 볼 수 있으며, 그 나머지가 세분되어 있는 형태이다.
쓰레드는 여러가지 메서드로 제어할 수 있는데, 중요한 것은 그 메서드가 static이냐 아니냐로 구분 될 수 있따.
static의 경우 현재 실행되고 있는 쓰레드에 적용이 된다.
만약 static메서드인 sleep을 th1.sleep()
이라는 메서드를 th2
에서 실행하게 된다면, th2가 잠시 쉬게 된다.
그래서 혼동을 방지하기 위해서 static 메서드는 반드시 Thread.*** 이런식으로 사용하는게 좋다.
현재 쓰레드를 일정시간동안 멈추게 한다.
public static native void sleep(long millis) throws InterruptedException;
public static void sleep(long millis, int nanos)
밀리초, 나노초로 지정할 수 있다. 약간의 시간오차는 있을 수 있다.
sleep()에서 깨는 방법은 두가지가 있다.
이 메서드는 반드시 예외처리를 해주어야한다.
그 이유는 interrupt()를 통해 깨는 원리가 sleep이 예외를 던지는 방식으로 이루어 지기 때문이다.
catch블럭 안에 아무것도 작성하지 않아도 문제 없다. (잠에서 깨는데만 사용됨)
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
//do nothing
}
메서드를 따로 만들어서 사용해도 된다.
자신에게 할당된 시간을 다른 쓰레드에게 양보
잘 쓰면 반응성을 높일 수 있음
예시)
while(true){
try{
Thread.sleep(3000);
} catch(InterruptedException e) {}
if (autosave){
autosave();
} else {
Thread.yield(); //이 부분
}
}
만약 yield가 없다면 시간이 낭비되는 작업이 반복된다.
OS 스케쥴러에게 통보를 하는 방식으로 반드시 동작한다는 보장은 없음
OS 스케쥴러 마음임.
static boolean interrupted ()
현재 쓰레드의 interrupted 상태를 알려주고 false로 초기화
false로 초기화 한다는 부분이 boolean isInterrupted()
와 다르다.
또한 중요한 점이 현재 쓰레드에 대해 적용된다는 점으로, 내가 코드를 작성한 그 쓰레드에 대한 값을 알려준다.
헷갈리기 쉽다.
public void interrupt()
sleep()에 대응됨. 자고있는 쓰레드를 깨운다.
이 메서드를 잘쓰면 반응성이 높아진다.
예를 들어 상태를 변경했는데 자고 있는 상태인 경우, 모두 잔 후 응답한다.
하지만 상태 변경 다음 interrupt() 를 호출하면, 무조건 바로 반응하게 된다.
boolean isInterrupted()
쓰레드의 interrupted 상태를 반환. static interrupted()와는 다르게 초기화는 하지 않음.
public final void join() throws InterruptedException
public final void join(long millis) throws InterruptedException
public final void join(long millis, int nano) throws InterruptedException
이 메서드를 호출한 쓰레드가 대상 쓰레드가 끝날때까지 기다림
sleep()과 마찬가지로 예외처리 필요
사용 ㄴㄴ